@azure/web-pubsub-express 1.0.0-alpha.20211001.2 → 1.0.0-alpha.20211108.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 +23 -1
- package/README.md +127 -31
- package/dist/index.js +52 -24
- package/dist/index.js.map +1 -1
- package/dist-esm/samples-dev/server.js +3 -3
- package/dist-esm/samples-dev/server.js.map +1 -1
- package/dist-esm/src/cloudEventsDispatcher.js +38 -18
- package/dist-esm/src/cloudEventsDispatcher.js.map +1 -1
- package/dist-esm/src/cloudEventsProtocols.js.map +1 -1
- package/dist-esm/src/logger.js +10 -0
- package/dist-esm/src/logger.js.map +1 -0
- package/dist-esm/src/webPubSubEventHandler.js +6 -6
- package/dist-esm/src/webPubSubEventHandler.js.map +1 -1
- package/dist-esm/test/connect.spec.js +25 -24
- package/dist-esm/test/connect.spec.js.map +1 -1
- package/dist-esm/test/connected.spec.js +11 -10
- package/dist-esm/test/connected.spec.js.map +1 -1
- package/dist-esm/test/ctor.spec.js +3 -3
- package/dist-esm/test/ctor.spec.js.map +1 -1
- package/dist-esm/test/disconnected.spec.js +11 -10
- package/dist-esm/test/disconnected.spec.js.map +1 -1
- package/dist-esm/test/user.spec.js +21 -20
- package/dist-esm/test/user.spec.js.map +1 -1
- package/dist-esm/test/validate.spec.js +26 -10
- package/dist-esm/test/validate.spec.js.map +1 -1
- package/package.json +2 -1
- package/types/web-pubsub-express.d.ts +11 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
-
## 1.0.0-beta.4 (
|
|
3
|
+
## 1.0.0-beta.4 (2021-11-01)
|
|
4
4
|
|
|
5
5
|
### Features Added
|
|
6
6
|
|
|
7
7
|
### Breaking Changes
|
|
8
8
|
|
|
9
|
+
- Move `allowedEndpoints` settings into `WebPubSubEventHandlerOptions`. If not set, the default behavior is allowing all the incoming endpoints.
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
const handler = new WebPubSubEventHandler("chat", {
|
|
13
|
+
handleConnect(req, res) {
|
|
14
|
+
// You can set the state for the connection, it lasts throughout the lifetime of the connection
|
|
15
|
+
res.setState("calledTime", 1);
|
|
16
|
+
res.success();
|
|
17
|
+
},
|
|
18
|
+
handleUserEvent(req, res) {
|
|
19
|
+
var calledTime = req.context.states.calledTime++;
|
|
20
|
+
console.log(calledTime);
|
|
21
|
+
// You can also set the state here
|
|
22
|
+
res.setState("calledTime", calledTime);
|
|
23
|
+
res.success();
|
|
24
|
+
},
|
|
25
|
+
allowedEndpoints: ["https://xxx.webpubsub.azure.com"]
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- Remove `dumpRequest` flag and leverage @azure/logger instead.
|
|
30
|
+
|
|
9
31
|
### Bugs Fixed
|
|
10
32
|
|
|
11
33
|
### Other Changes
|
package/README.md
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
# Azure Web PubSub CloudEvents handlers for Express
|
|
2
2
|
|
|
3
|
-
[Azure Web PubSub
|
|
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
|
-
|
|
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
|
-
|
|
7
|
+

|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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,6 +4,15 @@ 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');
|
|
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");
|
|
7
16
|
|
|
8
17
|
// Copyright (c) Microsoft Corporation.
|
|
9
18
|
// Licensed under the MIT license.
|
|
@@ -180,29 +189,51 @@ function tryGetWebPubSubEvent(req) {
|
|
|
180
189
|
return undefined;
|
|
181
190
|
}
|
|
182
191
|
}
|
|
192
|
+
function isWebPubSubRequest(req) {
|
|
193
|
+
return getHttpHeader(req, "ce-awpsversion") !== undefined;
|
|
194
|
+
}
|
|
183
195
|
/**
|
|
184
196
|
* @internal
|
|
185
197
|
*/
|
|
186
198
|
class CloudEventsDispatcher {
|
|
187
|
-
constructor(hub,
|
|
188
|
-
var _a;
|
|
199
|
+
constructor(hub, eventHandler) {
|
|
189
200
|
this.hub = hub;
|
|
190
201
|
this.eventHandler = eventHandler;
|
|
191
|
-
this.
|
|
192
|
-
this._allowedOrigins =
|
|
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
|
+
}
|
|
193
211
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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);
|
|
199
224
|
}
|
|
200
225
|
else {
|
|
201
|
-
|
|
226
|
+
logger.warning("Origin does not match the allowed origins: " + this._allowedOrigins);
|
|
227
|
+
res.statusCode = 400;
|
|
202
228
|
}
|
|
229
|
+
res.end();
|
|
230
|
+
return true;
|
|
203
231
|
}
|
|
204
|
-
async
|
|
232
|
+
async handleRequest(request, response) {
|
|
205
233
|
var _a, _b, _c, _d, _e;
|
|
234
|
+
if (!isWebPubSubRequest(request)) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
206
237
|
// check if it is a valid WebPubSub cloud events
|
|
207
238
|
const origin = getHttpHeader(request, "webhook-request-origin");
|
|
208
239
|
if (origin === undefined) {
|
|
@@ -221,8 +252,7 @@ class CloudEventsDispatcher {
|
|
|
221
252
|
switch (eventType) {
|
|
222
253
|
case EventType.Connect:
|
|
223
254
|
if (!((_a = this.eventHandler) === null || _a === void 0 ? void 0 : _a.handleConnect)) {
|
|
224
|
-
response.
|
|
225
|
-
response.end("Connect event handler is not configured.");
|
|
255
|
+
response.end();
|
|
226
256
|
return true;
|
|
227
257
|
}
|
|
228
258
|
break;
|
|
@@ -245,14 +275,12 @@ class CloudEventsDispatcher {
|
|
|
245
275
|
}
|
|
246
276
|
break;
|
|
247
277
|
default:
|
|
248
|
-
|
|
278
|
+
logger.warning(`Unknown EventType ${eventType}`);
|
|
249
279
|
return false;
|
|
250
280
|
}
|
|
251
281
|
const eventRequest = await convertHttpToEvent(request);
|
|
252
282
|
const receivedEvent = cloudevents.HTTP.toEvent(eventRequest);
|
|
253
|
-
|
|
254
|
-
console.log(receivedEvent);
|
|
255
|
-
}
|
|
283
|
+
logger.verbose(receivedEvent);
|
|
256
284
|
switch (eventType) {
|
|
257
285
|
case EventType.Connect: {
|
|
258
286
|
const connectRequest = receivedEvent.data;
|
|
@@ -301,7 +329,7 @@ class CloudEventsDispatcher {
|
|
|
301
329
|
return true;
|
|
302
330
|
}
|
|
303
331
|
default:
|
|
304
|
-
|
|
332
|
+
logger.warning(`Unknown EventType ${eventType}`);
|
|
305
333
|
return false;
|
|
306
334
|
}
|
|
307
335
|
}
|
|
@@ -320,7 +348,7 @@ class WebPubSubEventHandler {
|
|
|
320
348
|
* import express from "express";
|
|
321
349
|
* import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
|
|
322
350
|
* const endpoint = "https://xxxx.webpubsubdev.azure.com"
|
|
323
|
-
* const handler = new WebPubSubEventHandler('chat',
|
|
351
|
+
* const handler = new WebPubSubEventHandler('chat', {
|
|
324
352
|
* handleConnect: (req, res) => {
|
|
325
353
|
* console.log(JSON.stringify(req));
|
|
326
354
|
* return {};
|
|
@@ -332,20 +360,20 @@ class WebPubSubEventHandler {
|
|
|
332
360
|
* console.log(JSON.stringify(req));
|
|
333
361
|
* res.success("Hey " + req.data, req.dataType);
|
|
334
362
|
* };
|
|
363
|
+
* allowedEndpoints: [ endpoint ]
|
|
335
364
|
* },
|
|
336
365
|
* });
|
|
337
366
|
* ```
|
|
338
367
|
*
|
|
339
368
|
* @param hub - The name of the hub to listen to
|
|
340
|
-
* @param allowedEndpoints - The allowed endpoints for the incoming CloudEvents request
|
|
341
369
|
* @param options - Options to configure the event handler
|
|
342
370
|
*/
|
|
343
|
-
constructor(hub,
|
|
371
|
+
constructor(hub, options) {
|
|
344
372
|
var _a;
|
|
345
373
|
this.hub = hub;
|
|
346
374
|
const path = ((_a = options === null || options === void 0 ? void 0 : options.path) !== null && _a !== void 0 ? _a : `/api/webpubsub/hubs/${hub}/`).toLowerCase();
|
|
347
375
|
this.path = path.endsWith("/") ? path : path + "/";
|
|
348
|
-
this._cloudEventsHandler = new CloudEventsDispatcher(this.hub,
|
|
376
|
+
this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, options);
|
|
349
377
|
}
|
|
350
378
|
/**
|
|
351
379
|
* Get the middleware to process the CloudEvents requests
|
|
@@ -358,13 +386,13 @@ class WebPubSubEventHandler {
|
|
|
358
386
|
requestUrl = requestUrl.endsWith("/") ? requestUrl : requestUrl + "/";
|
|
359
387
|
if (requestUrl.startsWith(this.path)) {
|
|
360
388
|
if (req.method === "OPTIONS") {
|
|
361
|
-
if (this._cloudEventsHandler.
|
|
389
|
+
if (this._cloudEventsHandler.handlePreflight(req, res)) {
|
|
362
390
|
return;
|
|
363
391
|
}
|
|
364
392
|
}
|
|
365
393
|
else if (req.method === "POST") {
|
|
366
394
|
try {
|
|
367
|
-
if (await this._cloudEventsHandler.
|
|
395
|
+
if (await this._cloudEventsHandler.handleRequest(req, res)) {
|
|
368
396
|
return;
|
|
369
397
|
}
|
|
370
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":["// 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\";\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 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\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",
|
|
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
|
|
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"]}
|