@azure/web-pubsub-express 1.0.0-beta.3 → 1.0.1-alpha.20220103.2

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 CHANGED
@@ -1,5 +1,45 @@
1
1
  # Release History
2
2
 
3
+ ## 1.0.1 (Unreleased)
4
+
5
+ ### Features Added
6
+
7
+ ### Breaking Changes
8
+
9
+ ### Bugs Fixed
10
+
11
+ ### Other Changes
12
+
13
+ ## 1.0.0 (2021-11-11)
14
+
15
+ No changes.
16
+
17
+ ## 1.0.0-beta.4 (2021-11-09)
18
+
19
+ ### Breaking Changes
20
+
21
+ - Move `allowedEndpoints` settings into `WebPubSubEventHandlerOptions`. If not set, the default behavior is allowing all the incoming endpoints.
22
+
23
+ ```js
24
+ const handler = new WebPubSubEventHandler("chat", {
25
+ handleConnect(req, res) {
26
+ // You can set the state for the connection, it lasts throughout the lifetime of the connection
27
+ res.setState("calledTime", 1);
28
+ res.success();
29
+ },
30
+ handleUserEvent(req, res) {
31
+ var calledTime = req.context.states.calledTime++;
32
+ console.log(calledTime);
33
+ // You can also set the state here
34
+ res.setState("calledTime", calledTime);
35
+ res.success();
36
+ },
37
+ allowedEndpoints: ["https://xxx.webpubsub.azure.com"]
38
+ });
39
+ ```
40
+
41
+ - Remove `dumpRequest` flag and leverage @azure/logger instead.
42
+
3
43
  ## 1.0.0-beta.3 (2021-07-30)
4
44
 
5
45
  - Support reading and setting connection states, sample usage:
package/README.md CHANGED
@@ -1,21 +1,18 @@
1
1
  # Azure Web PubSub CloudEvents handlers for Express
2
2
 
3
- [Azure Web PubSub Service](https://aka.ms/awps/doc) is a service that enables you to build real-time messaging web applications using WebSockets and the publish-subscribe pattern. Any platform supporting WebSocket APIs can connect to the service easily, e.g. web pages, mobile applications, edge devices, etc. The service manages the WebSocket connections for you and allows up to 100K concurrent connections. It provides powerful APIs for you to manage these clients and deliver real-time messages.
3
+ [Azure Web PubSub service](https://aka.ms/awps/doc) is an Azure-managed service that helps developers easily build web applications with real-time features and publish-subscribe pattern. Any scenario that requires real-time publish-subscribe messaging between server and clients or among clients can use Azure Web PubSub service. Traditional real-time features that often require polling from server or submitting HTTP requests can also use Azure Web PubSub service.
4
4
 
5
- Any scenario that requires real-time publish-subscribe messaging between server and clients or among clients, can use Azure Web PubSub service. Traditional real-time features that often require polling from server or submitting HTTP requests, can also use Azure Web PubSub service.
5
+ When a WebSocket connection connects, the Web PubSub service transforms the connection lifecycle and messages into [events in CloudEvents format](https://docs.microsoft.com/azure/azure-web-pubsub/concept-service-internals#workflow). This library provides an express middleware to handle events representing the WebSocket connection's lifecycle and messages, as shown in below diagram:
6
6
 
7
- Use the express library to:
7
+ ![cloudevents](https://user-images.githubusercontent.com/668244/140321213-6442b3b8-72ee-4c28-aec1-127f9ea8f5d9.png)
8
8
 
9
- - Add Web PubSub CloudEvents middleware to handle incoming client events
10
- - Handle abuse validation requests
11
- - Handle client events requests
12
-
13
- Key links:
14
- - [Source code](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/web-pubsub/web-pubsub-express)
15
- - [Package (NPM)](https://www.npmjs.com/package/@azure/web-pubsub-express)
16
- - [API reference documentation](https://aka.ms/awps/sdk/js)
17
- - [Product documentation](https://aka.ms/awps/doc)
18
- - [Samples][samples_ref]
9
+ Details about the terms used here are described in [Key concepts](#key-concepts) section.
10
+
11
+ [Source code](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/web-pubsub/web-pubsub-express) |
12
+ [Package (NPM)](https://www.npmjs.com/package/@azure/web-pubsub-express) |
13
+ [API reference documentation](https://aka.ms/awps/sdk/js) |
14
+ [Product documentation](https://aka.ms/awps/doc) |
15
+ [Samples][samples_ref]
19
16
 
20
17
  ## Getting started
21
18
 
@@ -35,24 +32,13 @@ Key links:
35
32
  npm install @azure/web-pubsub-express
36
33
  ```
37
34
 
38
- ### 2. Create a WebPubSubEventHandler
35
+ ### 2. Create a `WebPubSubEventHandler`
39
36
 
40
37
  ```js
41
38
  const express = require("express");
42
39
 
43
40
  const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
44
- const handler = new WebPubSubEventHandler(
45
- "chat",
46
- ["https://<yourAllowedService>.webpubsub.azure.com"],
47
- {
48
- handleConnect: (req, res) => {
49
- // auth the connection and set the userId of the connection
50
- res.success({
51
- userId: "<userId>"
52
- });
53
- }
54
- }
55
- );
41
+ const handler = new WebPubSubEventHandler("chat");
56
42
 
57
43
  const app = express();
58
44
 
@@ -65,13 +51,17 @@ app.listen(3000, () =>
65
51
 
66
52
  ## Key concepts
67
53
 
54
+ ### Connection
55
+
56
+ A connection, also known as a client or a client connection, represents an individual WebSocket connection connected to the Web PubSub service. When successfully connected, a unique connection ID is assigned to this connection by the Web PubSub service.
57
+
68
58
  ### Hub
69
59
 
70
- Hub is a logic set of connections. All connections to Web PubSub connect to a specific hub. Messages that are broadcast to the hub are dispatched to all connections to that hub. For example, hub can be used for different applications, different applications can share one Azure Web PubSub service by using different hub names.
60
+ A hub is a logical concept for a set of client connections. Usually you use one hub for one purpose, for example, a chat hub, or a notification hub. When a client connection is created, it connects to a hub, and during its lifetime, it belongs to that hub. Different applications can share one Azure Web PubSub service by using different hub names.
71
61
 
72
62
  ### Group
73
63
 
74
- Group allow broadcast messages to a subset of connections to the hub. You can add and remove users and connections as needed. A client can join multiple groups, and a group can contain multiple clients.
64
+ A group is a subset of connections to the hub. You can add a client connection to a group, or remove the client connection from the group, anytime you want. For example, when a client joins a chat room, or when a client leaves the chat room, this chat room can be considered to be a group. A client can join multiple groups, and a group can contain multiple clients.
75
65
 
76
66
  ### User
77
67
 
@@ -87,11 +77,117 @@ Event handler contains the logic to handle the client events. Event handler need
87
77
 
88
78
  ## Examples
89
79
 
80
+ ### Handle the `connect` request and assign `<userId>`
81
+
82
+ ```js
83
+ const express = require("express");
84
+
85
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
86
+ const handler = new WebPubSubEventHandler("chat", {
87
+ handleConnect: (req, res) => {
88
+ // auth the connection and set the userId of the connection
89
+ res.success({
90
+ userId: "<userId>"
91
+ });
92
+ },
93
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
94
+ });
95
+
96
+ const app = express();
97
+
98
+ app.use(handler.getMiddleware());
99
+
100
+ app.listen(3000, () =>
101
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
102
+ );
103
+ ```
104
+
105
+ ### Only allow specified endpoints
106
+
107
+ ```js
108
+ const express = require("express");
109
+
110
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
111
+ const handler = new WebPubSubEventHandler("chat", {
112
+ allowedEndpoints: [
113
+ "https://<yourAllowedService1>.webpubsub.azure.com",
114
+ "https://<yourAllowedService2>.webpubsub.azure.com"
115
+ ]
116
+ });
117
+
118
+ const app = express();
119
+
120
+ app.use(handler.getMiddleware());
121
+
122
+ app.listen(3000, () =>
123
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
124
+ );
125
+ ```
126
+
127
+ ### Set custom event handler path
128
+
129
+ ```js
130
+ const express = require("express");
131
+
132
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
133
+ const handler = new WebPubSubEventHandler("chat", {
134
+ path: "customPath1"
135
+ });
136
+
137
+ const app = express();
138
+
139
+ app.use(handler.getMiddleware());
140
+
141
+ app.listen(3000, () =>
142
+ // Azure WebPubSub Upstream ready at http://localhost:3000/customPath1
143
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
144
+ );
145
+ ```
146
+
147
+ ### Set and read connection state
148
+
149
+ ```js
150
+ const express = require("express");
151
+
152
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
153
+
154
+ const handler = new WebPubSubEventHandler("chat", {
155
+ handleConnect(req, res) {
156
+ // You can set the state for the connection, it lasts throughout the lifetime of the connection
157
+ res.setState("calledTime", 1);
158
+ res.success();
159
+ },
160
+ handleUserEvent(req, res) {
161
+ var calledTime = req.context.states.calledTime++;
162
+ console.log(calledTime);
163
+ // You can also set the state here
164
+ res.setState("calledTime", calledTime);
165
+ res.success();
166
+ }
167
+ });
168
+
169
+ const app = express();
170
+
171
+ app.use(handler.getMiddleware());
172
+
173
+ app.listen(3000, () =>
174
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
175
+ );
176
+ ```
177
+
90
178
  ## Troubleshooting
91
179
 
92
- ### Dump request
180
+ ### Enable logs
181
+
182
+ You can set the following environment variable to get the debug logs when using this library.
183
+
184
+ - Getting debug logs from the SignalR client library
185
+
186
+ ```bash
187
+ export AZURE_LOG_LEVEL=verbose
188
+ ```
93
189
 
94
- Set `dumpRequest` to `true` to view the incoming requests.
190
+ For more detailed instructions on how to enable logs, you can look at the [@azure/logger package docs](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger).
95
191
 
96
192
  ### Live Trace
97
193
 
@@ -112,4 +208,4 @@ If you'd like to contribute to this library, please read the [contributing guide
112
208
  - [Microsoft Azure SDK for Javascript](https://github.com/Azure/azure-sdk-for-js)
113
209
 
114
210
  [azure_sub]: https://azure.microsoft.com/free/
115
- [samples_ref]: https://github.com/Azure/azure-webpubsub/tree/main/samples
211
+ [samples_ref]: https://github.com/Azure/azure-webpubsub/tree/main/samples/javascript/
package/dist/index.js CHANGED
@@ -4,7 +4,18 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var cloudevents = require('cloudevents');
6
6
  var url = require('url');
7
+ var logger$1 = require('@azure/logger');
7
8
 
9
+ // Copyright (c) Microsoft Corporation.
10
+ /**
11
+ * The \@azure/logger configuration for this package.
12
+ *
13
+ * @internal
14
+ */
15
+ const logger = logger$1.createClientLogger("web-pubsub-express");
16
+
17
+ // Copyright (c) Microsoft Corporation.
18
+ // Licensed under the MIT license.
8
19
  function isJsonObject(obj) {
9
20
  return obj && typeof obj === "object" && !Array.isArray(obj);
10
21
  }
@@ -16,8 +27,8 @@ function fromBase64JsonString(base64String) {
16
27
  return {};
17
28
  }
18
29
  try {
19
- let buf = Buffer.from(base64String, "base64").toString();
20
- let parsed = JSON.parse(buf);
30
+ const buf = Buffer.from(base64String, "base64").toString();
31
+ const parsed = JSON.parse(buf);
21
32
  return isJsonObject(parsed) ? parsed : {};
22
33
  }
23
34
  catch (e) {
@@ -38,7 +49,7 @@ function getHttpHeader(req, key) {
38
49
  async function convertHttpToEvent(request) {
39
50
  const normalized = {
40
51
  headers: {},
41
- body: ""
52
+ body: "",
42
53
  };
43
54
  if (request.headers) {
44
55
  for (const key in request.headers) {
@@ -80,7 +91,7 @@ var EventType;
80
91
  EventType[EventType["UserEvent"] = 3] = "UserEvent";
81
92
  })(EventType || (EventType = {}));
82
93
  function getConnectResponseHandler(connectRequest, response) {
83
- let states = connectRequest.context.states;
94
+ const states = connectRequest.context.states;
84
95
  let modified = false;
85
96
  const handler = {
86
97
  setState(name, value) {
@@ -103,12 +114,12 @@ function getConnectResponseHandler(connectRequest, response) {
103
114
  fail(code, detail) {
104
115
  response.statusCode = code;
105
116
  response.end(detail !== null && detail !== void 0 ? detail : "");
106
- }
117
+ },
107
118
  };
108
119
  return handler;
109
120
  }
110
121
  function getUserEventResponseHandler(userRequest, response) {
111
- let states = userRequest.context.states;
122
+ const states = userRequest.context.states;
112
123
  let modified = false;
113
124
  const handler = {
114
125
  setState(name, value) {
@@ -136,7 +147,7 @@ function getUserEventResponseHandler(userRequest, response) {
136
147
  fail(code, detail) {
137
148
  response.statusCode = code;
138
149
  response.end(detail !== null && detail !== void 0 ? detail : "");
139
- }
150
+ },
140
151
  };
141
152
  return handler;
142
153
  }
@@ -148,7 +159,7 @@ function getContext(ce, origin) {
148
159
  connectionId: ce["connectionid"],
149
160
  eventName: ce["eventname"],
150
161
  origin: origin,
151
- states: fromBase64JsonString(ce["connectionstate"])
162
+ states: fromBase64JsonString(ce["connectionstate"]),
152
163
  };
153
164
  // TODO: validation
154
165
  return context;
@@ -178,29 +189,51 @@ function tryGetWebPubSubEvent(req) {
178
189
  return undefined;
179
190
  }
180
191
  }
192
+ function isWebPubSubRequest(req) {
193
+ return getHttpHeader(req, "ce-awpsversion") !== undefined;
194
+ }
181
195
  /**
182
196
  * @internal
183
197
  */
184
198
  class CloudEventsDispatcher {
185
- constructor(hub, allowedEndpoints, eventHandler) {
186
- var _a;
199
+ constructor(hub, eventHandler) {
187
200
  this.hub = hub;
188
201
  this.eventHandler = eventHandler;
189
- this._dumpRequest = (_a = eventHandler === null || eventHandler === void 0 ? void 0 : eventHandler.dumpRequest) !== null && _a !== void 0 ? _a : false;
190
- this._allowedOrigins = allowedEndpoints.map((endpoint) => endpoint === "*" ? "*" : new url.URL(endpoint).host);
202
+ this._allowAll = true;
203
+ this._allowedOrigins = [];
204
+ if (Array.isArray(eventHandler)) {
205
+ throw new Error("Unexpected WebPubSubEventHandlerOptions");
206
+ }
207
+ if ((eventHandler === null || eventHandler === void 0 ? void 0 : eventHandler.allowedEndpoints) !== undefined) {
208
+ this._allowedOrigins = eventHandler.allowedEndpoints.map((endpoint) => new url.URL(endpoint).host.toLowerCase());
209
+ this._allowAll = false;
210
+ }
191
211
  }
192
- processValidateRequest(req, res) {
193
- if (req.headers["webhook-request-origin"]) {
194
- res.setHeader("WebHook-Allowed-Origin", this._allowedOrigins);
195
- res.end();
196
- return true;
212
+ handlePreflight(req, res) {
213
+ var _a;
214
+ if (!isWebPubSubRequest(req)) {
215
+ return false;
216
+ }
217
+ const origin = (_a = getHttpHeader(req, "webhook-request-origin")) === null || _a === void 0 ? void 0 : _a.toLowerCase();
218
+ if (origin === undefined) {
219
+ logger.warning("Expecting webhook-request-origin header.");
220
+ res.statusCode = 400;
221
+ }
222
+ else if (this._allowAll || this._allowedOrigins.indexOf(origin) > -1) {
223
+ res.setHeader("WebHook-Allowed-Origin", origin);
197
224
  }
198
225
  else {
199
- return false;
226
+ logger.warning("Origin does not match the allowed origins: " + this._allowedOrigins);
227
+ res.statusCode = 400;
200
228
  }
229
+ res.end();
230
+ return true;
201
231
  }
202
- async processRequest(request, response) {
232
+ async handleRequest(request, response) {
203
233
  var _a, _b, _c, _d, _e;
234
+ if (!isWebPubSubRequest(request)) {
235
+ return false;
236
+ }
204
237
  // check if it is a valid WebPubSub cloud events
205
238
  const origin = getHttpHeader(request, "webhook-request-origin");
206
239
  if (origin === undefined) {
@@ -219,8 +252,7 @@ class CloudEventsDispatcher {
219
252
  switch (eventType) {
220
253
  case EventType.Connect:
221
254
  if (!((_a = this.eventHandler) === null || _a === void 0 ? void 0 : _a.handleConnect)) {
222
- response.statusCode = 401;
223
- response.end("Connect event handler is not configured.");
255
+ response.end();
224
256
  return true;
225
257
  }
226
258
  break;
@@ -243,14 +275,12 @@ class CloudEventsDispatcher {
243
275
  }
244
276
  break;
245
277
  default:
246
- console.warn(`Unknown EventType ${eventType}`);
278
+ logger.warning(`Unknown EventType ${eventType}`);
247
279
  return false;
248
280
  }
249
281
  const eventRequest = await convertHttpToEvent(request);
250
282
  const receivedEvent = cloudevents.HTTP.toEvent(eventRequest);
251
- if (this._dumpRequest) {
252
- console.log(receivedEvent);
253
- }
283
+ logger.verbose(receivedEvent);
254
284
  switch (eventType) {
255
285
  case EventType.Connect: {
256
286
  const connectRequest = receivedEvent.data;
@@ -280,7 +310,7 @@ class CloudEventsDispatcher {
280
310
  userRequest = {
281
311
  context: getContext(receivedEvent, origin),
282
312
  data: Buffer.from(receivedEvent.data_base64, "base64"),
283
- dataType: "binary"
313
+ dataType: "binary",
284
314
  };
285
315
  }
286
316
  else if (receivedEvent.data !== undefined) {
@@ -289,7 +319,7 @@ class CloudEventsDispatcher {
289
319
  data: receivedEvent.data,
290
320
  dataType: ((_e = receivedEvent.datacontenttype) === null || _e === void 0 ? void 0 : _e.startsWith("application/json;"))
291
321
  ? "json"
292
- : "text"
322
+ : "text",
293
323
  };
294
324
  }
295
325
  else {
@@ -299,7 +329,7 @@ class CloudEventsDispatcher {
299
329
  return true;
300
330
  }
301
331
  default:
302
- console.warn(`Unknown EventType ${eventType}`);
332
+ logger.warning(`Unknown EventType ${eventType}`);
303
333
  return false;
304
334
  }
305
335
  }
@@ -318,7 +348,7 @@ class WebPubSubEventHandler {
318
348
  * import express from "express";
319
349
  * import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
320
350
  * const endpoint = "https://xxxx.webpubsubdev.azure.com"
321
- * const handler = new WebPubSubEventHandler('chat', [ endpoint ] {
351
+ * const handler = new WebPubSubEventHandler('chat', {
322
352
  * handleConnect: (req, res) => {
323
353
  * console.log(JSON.stringify(req));
324
354
  * return {};
@@ -330,20 +360,20 @@ class WebPubSubEventHandler {
330
360
  * console.log(JSON.stringify(req));
331
361
  * res.success("Hey " + req.data, req.dataType);
332
362
  * };
363
+ * allowedEndpoints: [ endpoint ]
333
364
  * },
334
365
  * });
335
366
  * ```
336
367
  *
337
- * @param hub The name of the hub to listen to
338
- * @param allowedEndpoints The allowed endpoints for the incoming CloudEvents request
339
- * @param options Options to configure the event handler
368
+ * @param hub - The name of the hub to listen to
369
+ * @param options - Options to configure the event handler
340
370
  */
341
- constructor(hub, allowedEndpoints, options) {
371
+ constructor(hub, options) {
342
372
  var _a;
343
373
  this.hub = hub;
344
374
  const path = ((_a = options === null || options === void 0 ? void 0 : options.path) !== null && _a !== void 0 ? _a : `/api/webpubsub/hubs/${hub}/`).toLowerCase();
345
375
  this.path = path.endsWith("/") ? path : path + "/";
346
- this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, allowedEndpoints, options);
376
+ this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, options);
347
377
  }
348
378
  /**
349
379
  * Get the middleware to process the CloudEvents requests
@@ -356,13 +386,13 @@ class WebPubSubEventHandler {
356
386
  requestUrl = requestUrl.endsWith("/") ? requestUrl : requestUrl + "/";
357
387
  if (requestUrl.startsWith(this.path)) {
358
388
  if (req.method === "OPTIONS") {
359
- if (this._cloudEventsHandler.processValidateRequest(req, res)) {
389
+ if (this._cloudEventsHandler.handlePreflight(req, res)) {
360
390
  return;
361
391
  }
362
392
  }
363
393
  else if (req.method === "POST") {
364
394
  try {
365
- if (await this._cloudEventsHandler.processRequest(req, res)) {
395
+ if (await this._cloudEventsHandler.handleRequest(req, res)) {
366
396
  return;
367
397
  }
368
398
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/cloudEventsDispatcher.ts","../src/webPubSubEventHandler.ts"],"sourcesContent":["import { IncomingMessage } from \"http\";\nimport { Message } from \"cloudevents\";\n\nfunction isJsonObject(obj: any) {\n return obj && typeof obj === \"object\" && !Array.isArray(obj);\n}\n\nexport function toBase64JsonString(obj: Record<string, any>): string {\n return Buffer.from(JSON.stringify(obj)).toString(\"base64\");\n}\n\nexport function fromBase64JsonString(base64String: string): Record<string, any> {\n if (base64String === undefined) {\n return {};\n }\n\n try {\n let buf = Buffer.from(base64String, \"base64\").toString();\n let parsed = JSON.parse(buf);\n return isJsonObject(parsed) ? parsed : {};\n } catch (e) {\n console.warn(\"Unexpected state format:\" + e);\n return {};\n }\n}\n\nexport function getHttpHeader(req: IncomingMessage, key: string): string | undefined {\n const value = req.headers[key];\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n return value[0];\n}\n\nexport async function convertHttpToEvent(request: IncomingMessage): Promise<Message> {\n const normalized: Message = {\n headers: {},\n body: \"\"\n };\n if (request.headers) {\n for (const key in request.headers) {\n if (Object.prototype.hasOwnProperty.call(request.headers, key)) {\n const element = request.headers[key];\n if (element !== undefined) {\n normalized.headers[key.toLowerCase()] = element;\n }\n }\n }\n }\n\n normalized.body = await readRequestBody(request);\n return normalized;\n}\n\nexport function readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise(function(resolve, reject) {\n const chunks: any = [];\n req.on(\"data\", function(chunk) {\n chunks.push(chunk);\n });\n req.on(\"end\", function() {\n const buffer = Buffer.concat(chunks);\n resolve(buffer.toString());\n });\n // reject on request error\n req.on(\"error\", function(err) {\n // This is not a \"Second reject\", just a different sort of failure\n reject(err);\n });\n });\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { HTTP, CloudEvent } from \"cloudevents\";\nimport { IncomingMessage, ServerResponse } from \"http\";\nimport { URL } from \"url\";\n\nimport * as utils from \"./utils\";\n\nimport {\n ConnectRequest,\n ConnectResponse,\n UserEventRequest,\n DisconnectedRequest,\n ConnectedRequest,\n ConnectionContext,\n WebPubSubEventHandlerOptions,\n ConnectResponseHandler,\n UserEventResponseHandler\n} from \"./cloudEventsProtocols\";\n\nenum EventType {\n Connect,\n Connected,\n Disconnected,\n UserEvent\n}\n\nfunction getConnectResponseHandler(\n connectRequest: ConnectRequest,\n response: ServerResponse\n): ConnectResponseHandler {\n let states: Record<string, any> = connectRequest.context.states;\n let modified = false;\n const handler = {\n setState(name: string, value: unknown): void {\n states[name] = value;\n modified = true;\n },\n success(res?: ConnectResponse): void {\n response.statusCode = 200;\n if (modified) {\n response.setHeader(\"ce-connectionState\", utils.toBase64JsonString(states));\n }\n if (res === undefined) {\n response.end();\n } else {\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n response.end(JSON.stringify(res));\n }\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n }\n };\n\n return handler;\n}\n\nfunction getUserEventResponseHandler(\n userRequest: UserEventRequest,\n response: ServerResponse\n): UserEventResponseHandler {\n let states: Record<string, any> = userRequest.context.states;\n let modified = false;\n const handler = {\n setState(name: string, value: unknown): void {\n modified = true;\n states[name] = value;\n },\n success(data?: string | ArrayBuffer, dataType?: \"binary\" | \"text\" | \"json\"): void {\n response.statusCode = 200;\n if (modified) {\n response.setHeader(\"ce-connectionState\", utils.toBase64JsonString(states));\n }\n\n switch (dataType) {\n case \"json\":\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n break;\n case \"text\":\n response.setHeader(\"Content-Type\", \"text/plain; charset=utf-8\");\n break;\n default:\n response.setHeader(\"Content-Type\", \"application/octet-stream\");\n break;\n }\n response.end(data ?? \"\");\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n }\n };\n return handler;\n}\n\nfunction getContext(ce: CloudEvent, origin: string): ConnectionContext {\n const context = {\n signature: ce[\"signature\"] as string,\n userId: ce[\"userid\"] as string,\n hub: ce[\"hub\"] as string,\n connectionId: ce[\"connectionid\"] as string,\n eventName: ce[\"eventname\"] as string,\n origin: origin,\n states: utils.fromBase64JsonString(ce[\"connectionstate\"] as string)\n };\n\n // TODO: validation\n return context;\n}\n\nfunction tryGetWebPubSubEvent(req: IncomingMessage): EventType | undefined {\n // check ce-type to see if it is a valid WebPubSub CloudEvent request\n const prefix = \"azure.webpubsub.\";\n const connect = \"azure.webpubsub.sys.connect\";\n const connected = \"azure.webpubsub.sys.connected\";\n const disconnectd = \"azure.webpubsub.sys.disconnected\";\n const userPrefix = \"azure.webpubsub.user.\";\n const type = utils.getHttpHeader(req, \"ce-type\");\n if (!type?.startsWith(prefix)) {\n return undefined;\n }\n if (type.startsWith(userPrefix)) {\n return EventType.UserEvent;\n }\n switch (type) {\n case connect:\n return EventType.Connect;\n case connected:\n return EventType.Connected;\n case disconnectd:\n return EventType.Disconnected;\n default:\n return undefined;\n }\n}\n\n/**\n * @internal\n */\nexport class CloudEventsDispatcher {\n private readonly _dumpRequest: boolean;\n private readonly _allowedOrigins: string[];\n constructor(\n private hub: string,\n allowedEndpoints: string[],\n private eventHandler?: WebPubSubEventHandlerOptions\n ) {\n this._dumpRequest = eventHandler?.dumpRequest ?? false;\n this._allowedOrigins = allowedEndpoints.map((endpoint) =>\n endpoint === \"*\" ? \"*\" : new URL(endpoint).host\n );\n }\n\n public processValidateRequest(req: IncomingMessage, res: ServerResponse): boolean {\n if (req.headers[\"webhook-request-origin\"]) {\n res.setHeader(\"WebHook-Allowed-Origin\", this._allowedOrigins);\n res.end();\n return true;\n } else {\n return false;\n }\n }\n\n public async processRequest(\n request: IncomingMessage,\n response: ServerResponse\n ): Promise<boolean> {\n // check if it is a valid WebPubSub cloud events\n const origin = utils.getHttpHeader(request, \"webhook-request-origin\");\n if (origin === undefined) {\n return false;\n }\n\n const eventType = tryGetWebPubSubEvent(request);\n if (eventType === undefined) {\n return false;\n }\n\n // check if hub matches\n const hub = utils.getHttpHeader(request, \"ce-hub\");\n if (hub !== this.hub) {\n return false;\n }\n\n // No need to read body if handler is not specified\n switch (eventType) {\n case EventType.Connect:\n if (!this.eventHandler?.handleConnect) {\n response.statusCode = 401;\n response.end(\"Connect event handler is not configured.\");\n return true;\n }\n break;\n case EventType.Connected:\n if (!this.eventHandler?.onConnected) {\n response.end();\n return true;\n }\n break;\n case EventType.Disconnected:\n if (!this.eventHandler?.onDisconnected) {\n response.end();\n return true;\n }\n break;\n case EventType.UserEvent:\n if (!this.eventHandler?.handleUserEvent) {\n response.end();\n return true;\n }\n break;\n default:\n console.warn(`Unknown EventType ${eventType}`);\n return false;\n }\n\n const eventRequest = await utils.convertHttpToEvent(request);\n const receivedEvent = HTTP.toEvent(eventRequest);\n\n if (this._dumpRequest) {\n console.log(receivedEvent);\n }\n\n switch (eventType) {\n case EventType.Connect: {\n const connectRequest = receivedEvent.data as ConnectRequest;\n connectRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.handleConnect!(\n connectRequest,\n getConnectResponseHandler(connectRequest, response)\n );\n return true;\n }\n case EventType.Connected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const connectedRequest = receivedEvent.data as ConnectedRequest;\n connectedRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.onConnected!(connectedRequest);\n return true;\n }\n case EventType.Disconnected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const disconnectedRequest = receivedEvent.data as DisconnectedRequest;\n disconnectedRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.onDisconnected!(disconnectedRequest);\n return true;\n }\n case EventType.UserEvent: {\n let userRequest: UserEventRequest;\n if (receivedEvent.data_base64 !== undefined) {\n userRequest = {\n context: getContext(receivedEvent, origin),\n data: Buffer.from(receivedEvent.data_base64, \"base64\"),\n dataType: \"binary\"\n };\n } else if (receivedEvent.data !== undefined) {\n userRequest = {\n context: getContext(receivedEvent, origin),\n data: receivedEvent.data as string,\n dataType: receivedEvent.datacontenttype?.startsWith(\"application/json;\")\n ? \"json\"\n : \"text\"\n };\n } else {\n throw new Error(\"Unexpected data.\");\n }\n\n this.eventHandler.handleUserEvent!(\n userRequest,\n getUserEventResponseHandler(userRequest, response)\n );\n return true;\n }\n default:\n console.warn(`Unknown EventType ${eventType}`);\n return false;\n }\n }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport express from \"express-serve-static-core\";\n\nimport { CloudEventsDispatcher } from \"./cloudEventsDispatcher\";\nimport { WebPubSubEventHandlerOptions } from \"./cloudEventsProtocols\";\n\n/**\n * The handler to handle incoming CloudEvents messages\n */\nexport class WebPubSubEventHandler {\n /**\n * The path this CloudEvents handler listens to\n */\n public readonly path: string;\n\n private _cloudEventsHandler: CloudEventsDispatcher;\n\n /**\n * Creates an instance of a WebPubSubEventHandler for handling incoming CloudEvents messages.\n *\n * Example usage:\n * ```ts\n * import express from \"express\";\n * import { WebPubSubEventHandler } from \"@azure/web-pubsub-express\";\n * const endpoint = \"https://xxxx.webpubsubdev.azure.com\"\n * const handler = new WebPubSubEventHandler('chat', [ endpoint ] {\n * handleConnect: (req, res) => {\n * console.log(JSON.stringify(req));\n * return {};\n * },\n * onConnected: req => {\n * console.log(JSON.stringify(req));\n * },\n * handleUserEvent: (req, res) => {\n * console.log(JSON.stringify(req));\n * res.success(\"Hey \" + req.data, req.dataType);\n * };\n * },\n * });\n * ```\n *\n * @param hub The name of the hub to listen to\n * @param allowedEndpoints The allowed endpoints for the incoming CloudEvents request\n * @param options Options to configure the event handler\n */\n constructor(\n private hub: string,\n allowedEndpoints: string[],\n options?: WebPubSubEventHandlerOptions\n ) {\n const path = (options?.path ?? `/api/webpubsub/hubs/${hub}/`).toLowerCase();\n this.path = path.endsWith(\"/\") ? path : path + \"/\";\n this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, allowedEndpoints, options);\n }\n\n /**\n * Get the middleware to process the CloudEvents requests\n */\n public getMiddleware(): express.RequestHandler {\n return async (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction\n ): Promise<void> => {\n // Request originalUrl can contain query while baseUrl + path not\n let requestUrl = (req.baseUrl + req.path).toLowerCase();\n\n // normalize the Url\n requestUrl = requestUrl.endsWith(\"/\") ? requestUrl : requestUrl + \"/\";\n if (requestUrl.startsWith(this.path)) {\n if (req.method === \"OPTIONS\") {\n if (this._cloudEventsHandler.processValidateRequest(req, res)) {\n return;\n }\n } else if (req.method === \"POST\") {\n try {\n if (await this._cloudEventsHandler.processRequest(req, res)) {\n return;\n }\n } catch (err) {\n next(err);\n return;\n }\n }\n }\n\n next();\n };\n }\n}\n"],"names":["utils.toBase64JsonString","utils.fromBase64JsonString","utils.getHttpHeader","URL","utils.convertHttpToEvent","HTTP"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/logger.ts","../src/utils.ts","../src/cloudEventsDispatcher.ts","../src/webPubSubEventHandler.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createClientLogger } from \"@azure/logger\";\n\n/**\n * The \\@azure/logger configuration for this package.\n *\n * @internal\n */\nexport const logger = createClientLogger(\"web-pubsub-express\");\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { IncomingMessage } from \"http\";\nimport { Message } from \"cloudevents\";\n\nfunction isJsonObject(obj: any): boolean {\n return obj && typeof obj === \"object\" && !Array.isArray(obj);\n}\n\nexport function toBase64JsonString(obj: Record<string, any>): string {\n return Buffer.from(JSON.stringify(obj)).toString(\"base64\");\n}\n\nexport function fromBase64JsonString(base64String: string): Record<string, any> {\n if (base64String === undefined) {\n return {};\n }\n\n try {\n const buf = Buffer.from(base64String, \"base64\").toString();\n const parsed = JSON.parse(buf);\n return isJsonObject(parsed) ? parsed : {};\n } catch (e) {\n console.warn(\"Unexpected state format:\" + e);\n return {};\n }\n}\n\nexport function getHttpHeader(req: IncomingMessage, key: string): string | undefined {\n const value = req.headers[key];\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n return value[0];\n}\n\nexport async function convertHttpToEvent(request: IncomingMessage): Promise<Message> {\n const normalized: Message = {\n headers: {},\n body: \"\",\n };\n if (request.headers) {\n for (const key in request.headers) {\n if (Object.prototype.hasOwnProperty.call(request.headers, key)) {\n const element = request.headers[key];\n if (element !== undefined) {\n normalized.headers[key.toLowerCase()] = element;\n }\n }\n }\n }\n\n normalized.body = await readRequestBody(request);\n return normalized;\n}\n\nexport function readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise(function (resolve, reject) {\n const chunks: any = [];\n req.on(\"data\", function (chunk) {\n chunks.push(chunk);\n });\n req.on(\"end\", function () {\n const buffer = Buffer.concat(chunks);\n resolve(buffer.toString());\n });\n // reject on request error\n req.on(\"error\", function (err) {\n // This is not a \"Second reject\", just a different sort of failure\n reject(err);\n });\n });\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { HTTP, CloudEvent } from \"cloudevents\";\nimport { IncomingMessage, ServerResponse } from \"http\";\nimport { URL } from \"url\";\nimport { logger } from \"./logger\";\nimport * as utils from \"./utils\";\n\nimport {\n ConnectRequest,\n ConnectResponse,\n UserEventRequest,\n DisconnectedRequest,\n ConnectedRequest,\n ConnectionContext,\n ConnectResponseHandler,\n UserEventResponseHandler,\n WebPubSubEventHandlerOptions,\n} from \"./cloudEventsProtocols\";\n\nenum EventType {\n Connect,\n Connected,\n Disconnected,\n UserEvent,\n}\n\nfunction getConnectResponseHandler(\n connectRequest: ConnectRequest,\n response: ServerResponse\n): ConnectResponseHandler {\n const states: Record<string, any> = connectRequest.context.states;\n let modified = false;\n const handler = {\n setState(name: string, value: unknown): void {\n states[name] = value;\n modified = true;\n },\n success(res?: ConnectResponse): void {\n response.statusCode = 200;\n if (modified) {\n response.setHeader(\"ce-connectionState\", utils.toBase64JsonString(states));\n }\n if (res === undefined) {\n response.end();\n } else {\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n response.end(JSON.stringify(res));\n }\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n },\n };\n\n return handler;\n}\n\nfunction getUserEventResponseHandler(\n userRequest: UserEventRequest,\n response: ServerResponse\n): UserEventResponseHandler {\n const states: Record<string, any> = userRequest.context.states;\n let modified = false;\n const handler = {\n setState(name: string, value: unknown): void {\n modified = true;\n states[name] = value;\n },\n success(data?: string | ArrayBuffer, dataType?: \"binary\" | \"text\" | \"json\"): void {\n response.statusCode = 200;\n if (modified) {\n response.setHeader(\"ce-connectionState\", utils.toBase64JsonString(states));\n }\n\n switch (dataType) {\n case \"json\":\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n break;\n case \"text\":\n response.setHeader(\"Content-Type\", \"text/plain; charset=utf-8\");\n break;\n default:\n response.setHeader(\"Content-Type\", \"application/octet-stream\");\n break;\n }\n response.end(data ?? \"\");\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n },\n };\n return handler;\n}\n\nfunction getContext(ce: CloudEvent, origin: string): ConnectionContext {\n const context = {\n signature: ce[\"signature\"] as string,\n userId: ce[\"userid\"] as string,\n hub: ce[\"hub\"] as string,\n connectionId: ce[\"connectionid\"] as string,\n eventName: ce[\"eventname\"] as string,\n origin: origin,\n states: utils.fromBase64JsonString(ce[\"connectionstate\"] as string),\n };\n\n // TODO: validation\n return context;\n}\n\nfunction tryGetWebPubSubEvent(req: IncomingMessage): EventType | undefined {\n // check ce-type to see if it is a valid WebPubSub CloudEvent request\n const prefix = \"azure.webpubsub.\";\n const connect = \"azure.webpubsub.sys.connect\";\n const connected = \"azure.webpubsub.sys.connected\";\n const disconnectd = \"azure.webpubsub.sys.disconnected\";\n const userPrefix = \"azure.webpubsub.user.\";\n const type = utils.getHttpHeader(req, \"ce-type\");\n if (!type?.startsWith(prefix)) {\n return undefined;\n }\n if (type.startsWith(userPrefix)) {\n return EventType.UserEvent;\n }\n switch (type) {\n case connect:\n return EventType.Connect;\n case connected:\n return EventType.Connected;\n case disconnectd:\n return EventType.Disconnected;\n default:\n return undefined;\n }\n}\n\nfunction isWebPubSubRequest(req: IncomingMessage): boolean {\n return utils.getHttpHeader(req, \"ce-awpsversion\") !== undefined;\n}\n\n/**\n * @internal\n */\nexport class CloudEventsDispatcher {\n private readonly _allowAll: boolean = true;\n private readonly _allowedOrigins: Array<string> = [];\n constructor(private hub: string, private eventHandler?: WebPubSubEventHandlerOptions) {\n if (Array.isArray(eventHandler)) {\n throw new Error(\"Unexpected WebPubSubEventHandlerOptions\");\n }\n if (eventHandler?.allowedEndpoints !== undefined) {\n this._allowedOrigins = eventHandler.allowedEndpoints.map((endpoint) =>\n new URL(endpoint).host.toLowerCase()\n );\n this._allowAll = false;\n }\n }\n\n public handlePreflight(req: IncomingMessage, res: ServerResponse): boolean {\n if (!isWebPubSubRequest(req)) {\n return false;\n }\n const origin = utils.getHttpHeader(req, \"webhook-request-origin\")?.toLowerCase();\n\n if (origin === undefined) {\n logger.warning(\"Expecting webhook-request-origin header.\");\n res.statusCode = 400;\n } else if (this._allowAll || this._allowedOrigins.indexOf(origin!) > -1) {\n res.setHeader(\"WebHook-Allowed-Origin\", origin!);\n } else {\n logger.warning(\"Origin does not match the allowed origins: \" + this._allowedOrigins);\n res.statusCode = 400;\n }\n\n res.end();\n return true;\n }\n\n public async handleRequest(request: IncomingMessage, response: ServerResponse): Promise<boolean> {\n if (!isWebPubSubRequest(request)) {\n return false;\n }\n\n // check if it is a valid WebPubSub cloud events\n const origin = utils.getHttpHeader(request, \"webhook-request-origin\");\n if (origin === undefined) {\n return false;\n }\n\n const eventType = tryGetWebPubSubEvent(request);\n if (eventType === undefined) {\n return false;\n }\n\n // check if hub matches\n const hub = utils.getHttpHeader(request, \"ce-hub\");\n if (hub !== this.hub) {\n return false;\n }\n\n // No need to read body if handler is not specified\n switch (eventType) {\n case EventType.Connect:\n if (!this.eventHandler?.handleConnect) {\n response.end();\n return true;\n }\n break;\n case EventType.Connected:\n if (!this.eventHandler?.onConnected) {\n response.end();\n return true;\n }\n break;\n case EventType.Disconnected:\n if (!this.eventHandler?.onDisconnected) {\n response.end();\n return true;\n }\n break;\n case EventType.UserEvent:\n if (!this.eventHandler?.handleUserEvent) {\n response.end();\n return true;\n }\n break;\n default:\n logger.warning(`Unknown EventType ${eventType}`);\n return false;\n }\n\n const eventRequest = await utils.convertHttpToEvent(request);\n const receivedEvent = HTTP.toEvent(eventRequest);\n\n logger.verbose(receivedEvent);\n\n switch (eventType) {\n case EventType.Connect: {\n const connectRequest = receivedEvent.data as ConnectRequest;\n connectRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.handleConnect!(\n connectRequest,\n getConnectResponseHandler(connectRequest, response)\n );\n return true;\n }\n case EventType.Connected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const connectedRequest = receivedEvent.data as ConnectedRequest;\n connectedRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.onConnected!(connectedRequest);\n return true;\n }\n case EventType.Disconnected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const disconnectedRequest = receivedEvent.data as DisconnectedRequest;\n disconnectedRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.onDisconnected!(disconnectedRequest);\n return true;\n }\n case EventType.UserEvent: {\n let userRequest: UserEventRequest;\n if (receivedEvent.data_base64 !== undefined) {\n userRequest = {\n context: getContext(receivedEvent, origin),\n data: Buffer.from(receivedEvent.data_base64, \"base64\"),\n dataType: \"binary\",\n };\n } else if (receivedEvent.data !== undefined) {\n userRequest = {\n context: getContext(receivedEvent, origin),\n data: receivedEvent.data as string,\n dataType: receivedEvent.datacontenttype?.startsWith(\"application/json;\")\n ? \"json\"\n : \"text\",\n };\n } else {\n throw new Error(\"Unexpected data.\");\n }\n\n this.eventHandler.handleUserEvent!(\n userRequest,\n getUserEventResponseHandler(userRequest, response)\n );\n return true;\n }\n default:\n logger.warning(`Unknown EventType ${eventType}`);\n return false;\n }\n }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport express from \"express-serve-static-core\";\n\nimport { CloudEventsDispatcher } from \"./cloudEventsDispatcher\";\nimport { WebPubSubEventHandlerOptions } from \"./cloudEventsProtocols\";\n\n/**\n * The handler to handle incoming CloudEvents messages\n */\nexport class WebPubSubEventHandler {\n /**\n * The path this CloudEvents handler listens to\n */\n public readonly path: string;\n\n private _cloudEventsHandler: CloudEventsDispatcher;\n\n /**\n * Creates an instance of a WebPubSubEventHandler for handling incoming CloudEvents messages.\n *\n * Example usage:\n * ```ts\n * import express from \"express\";\n * import { WebPubSubEventHandler } from \"@azure/web-pubsub-express\";\n * const endpoint = \"https://xxxx.webpubsubdev.azure.com\"\n * const handler = new WebPubSubEventHandler('chat', {\n * handleConnect: (req, res) => {\n * console.log(JSON.stringify(req));\n * return {};\n * },\n * onConnected: req => {\n * console.log(JSON.stringify(req));\n * },\n * handleUserEvent: (req, res) => {\n * console.log(JSON.stringify(req));\n * res.success(\"Hey \" + req.data, req.dataType);\n * };\n * allowedEndpoints: [ endpoint ]\n * },\n * });\n * ```\n *\n * @param hub - The name of the hub to listen to\n * @param options - Options to configure the event handler\n */\n constructor(private hub: string, options?: WebPubSubEventHandlerOptions) {\n const path = (options?.path ?? `/api/webpubsub/hubs/${hub}/`).toLowerCase();\n this.path = path.endsWith(\"/\") ? path : path + \"/\";\n this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, options);\n }\n\n /**\n * Get the middleware to process the CloudEvents requests\n */\n public getMiddleware(): express.RequestHandler {\n return async (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction\n ): Promise<void> => {\n // Request originalUrl can contain query while baseUrl + path not\n let requestUrl = (req.baseUrl + req.path).toLowerCase();\n\n // normalize the Url\n requestUrl = requestUrl.endsWith(\"/\") ? requestUrl : requestUrl + \"/\";\n if (requestUrl.startsWith(this.path)) {\n if (req.method === \"OPTIONS\") {\n if (this._cloudEventsHandler.handlePreflight(req, res)) {\n return;\n }\n } else if (req.method === \"POST\") {\n try {\n if (await this._cloudEventsHandler.handleRequest(req, res)) {\n return;\n }\n } catch (err) {\n next(err);\n return;\n }\n }\n }\n\n next();\n };\n }\n}\n"],"names":["createClientLogger","utils.toBase64JsonString","utils.fromBase64JsonString","utils.getHttpHeader","URL","utils.convertHttpToEvent","HTTP"],"mappings":"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"}
@@ -5,8 +5,7 @@
5
5
  */
6
6
  import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
7
7
  import express from "express";
8
- const handler = new WebPubSubEventHandler("chat", ["https://xxx.webpubsub.azure.com"], {
9
- dumpRequest: false,
8
+ const handler = new WebPubSubEventHandler("chat", {
10
9
  handleConnect(req, res) {
11
10
  console.log(req);
12
11
  // You can set the state for the connection, it lasts throughout the lifetime of the connection
@@ -24,7 +23,8 @@ const handler = new WebPubSubEventHandler("chat", ["https://xxx.webpubsub.azure.
24
23
  // You can also set the state here
25
24
  res.setState("calledTime", calledTime);
26
25
  res.success("Hello", "text");
27
- }
26
+ },
27
+ allowedEndpoints: ["https://xxx.webpubsub.azure.com"],
28
28
  });
29
29
  const app = express();
30
30
  app.use(handler.getMiddleware());
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../samples-dev/server.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,MAAM,EAAE,CAAC,iCAAiC,CAAC,EAAE;IACrF,WAAW,EAAE,KAAK;IAClB,aAAa,CAAC,GAAG,EAAE,GAAG;QACpB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,+FAA+F;QAC/F,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QAC9B,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,UAAU;QACV,iBAAiB;IACnB,CAAC;IACD,WAAW,CAAC,gBAAgB;QAC1B,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IACD,eAAe,CAAC,GAAG,EAAE,GAAG;QACtB,IAAI,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,kCAAkC;QAClC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACvC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;AAEjC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CACpB,OAAO,CAAC,GAAG,CAAC,0DAA0D,OAAO,CAAC,IAAI,EAAE,CAAC,CACtF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * @summary Demonstrates handling Web PubSub CloudEvents with Express\n */\n\nimport { WebPubSubEventHandler } from \"@azure/web-pubsub-express\";\nimport express from \"express\";\n\nconst handler = new WebPubSubEventHandler(\"chat\", [\"https://xxx.webpubsub.azure.com\"], {\n dumpRequest: false,\n handleConnect(req, res) {\n console.log(req);\n // You can set the state for the connection, it lasts throughout the lifetime of the connection\n res.setState(\"calledTime\", 1);\n res.success();\n // or fail\n // res.fail(401);\n },\n onConnected(connectedRequest) {\n console.log(connectedRequest);\n },\n handleUserEvent(req, res) {\n var calledTime = req.context.states.calledTime++;\n console.log(calledTime);\n // You can also set the state here\n res.setState(\"calledTime\", calledTime);\n res.success(\"Hello\", \"text\");\n }\n});\n\nconst app = express();\n\napp.use(handler.getMiddleware());\n\napp.listen(3000, () =>\n console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)\n);\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../samples-dev/server.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,MAAM,EAAE;IAChD,aAAa,CAAC,GAAG,EAAE,GAAG;QACpB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,+FAA+F;QAC/F,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QAC9B,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,UAAU;QACV,iBAAiB;IACnB,CAAC;IACD,WAAW,CAAC,gBAAgB;QAC1B,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IACD,eAAe,CAAC,GAAG,EAAE,GAAG;QACtB,IAAI,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,kCAAkC;QAClC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACvC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,gBAAgB,EAAE,CAAC,iCAAiC,CAAC;CACtD,CAAC,CAAC;AAEH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;AAEjC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CACpB,OAAO,CAAC,GAAG,CAAC,0DAA0D,OAAO,CAAC,IAAI,EAAE,CAAC,CACtF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * @summary Demonstrates handling Web PubSub CloudEvents with Express\n */\n\nimport { WebPubSubEventHandler } from \"@azure/web-pubsub-express\";\nimport express from \"express\";\n\nconst handler = new WebPubSubEventHandler(\"chat\", {\n handleConnect(req, res) {\n console.log(req);\n // You can set the state for the connection, it lasts throughout the lifetime of the connection\n res.setState(\"calledTime\", 1);\n res.success();\n // or fail\n // res.fail(401);\n },\n onConnected(connectedRequest) {\n console.log(connectedRequest);\n },\n handleUserEvent(req, res) {\n var calledTime = req.context.states.calledTime++;\n console.log(calledTime);\n // You can also set the state here\n res.setState(\"calledTime\", calledTime);\n res.success(\"Hello\", \"text\");\n },\n allowedEndpoints: [\"https://xxx.webpubsub.azure.com\"],\n});\n\nconst app = express();\n\napp.use(handler.getMiddleware());\n\napp.listen(3000, () =>\n console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)\n);\n"]}