@azure/web-pubsub-express 1.0.6-alpha.20250224.1 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +53 -46
  2. package/dist/browser/cloudEventsDispatcher.d.ts +15 -0
  3. package/dist/browser/cloudEventsDispatcher.d.ts.map +1 -0
  4. package/dist/browser/cloudEventsDispatcher.js +411 -0
  5. package/dist/browser/cloudEventsDispatcher.js.map +1 -0
  6. package/dist/browser/cloudEventsProtocols.d.ts +411 -0
  7. package/dist/browser/cloudEventsProtocols.d.ts.map +1 -0
  8. package/dist/browser/cloudEventsProtocols.js +4 -0
  9. package/dist/browser/cloudEventsProtocols.js.map +1 -0
  10. package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts +180 -0
  11. package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts.map +1 -0
  12. package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.js +183 -0
  13. package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.js.map +1 -0
  14. package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts +31 -0
  15. package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts.map +1 -0
  16. package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js +34 -0
  17. package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js.map +1 -0
  18. package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts +112 -0
  19. package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts.map +1 -0
  20. package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js +115 -0
  21. package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js.map +1 -0
  22. package/dist/browser/index.d.ts +6 -0
  23. package/dist/browser/index.d.ts.map +1 -0
  24. package/dist/browser/index.js +8 -0
  25. package/dist/browser/index.js.map +1 -0
  26. package/dist/browser/logger.d.ts +7 -0
  27. package/dist/browser/logger.d.ts.map +1 -0
  28. package/dist/browser/logger.js +10 -0
  29. package/dist/browser/logger.js.map +1 -0
  30. package/dist/browser/package.json +3 -0
  31. package/dist/browser/utils.d.ts +6 -0
  32. package/dist/browser/utils.d.ts.map +1 -0
  33. package/dist/browser/utils.js +53 -0
  34. package/dist/browser/utils.js.map +1 -0
  35. package/dist/browser/webPubSubEventHandler.d.ts +46 -0
  36. package/dist/browser/webPubSubEventHandler.d.ts.map +1 -0
  37. package/dist/browser/webPubSubEventHandler.js +73 -0
  38. package/dist/browser/webPubSubEventHandler.js.map +1 -0
  39. package/dist/commonjs/index.js +14 -880
  40. package/dist/commonjs/index.js.map +1 -1
  41. package/dist/commonjs/webPubSubEventHandler.d.ts +7 -8
  42. package/dist/commonjs/webPubSubEventHandler.d.ts.map +1 -1
  43. package/dist/commonjs/webPubSubEventHandler.js +7 -8
  44. package/dist/commonjs/webPubSubEventHandler.js.map +1 -1
  45. package/dist/esm/webPubSubEventHandler.d.ts +7 -8
  46. package/dist/esm/webPubSubEventHandler.d.ts.map +1 -1
  47. package/dist/esm/webPubSubEventHandler.js +7 -8
  48. package/dist/esm/webPubSubEventHandler.js.map +1 -1
  49. package/dist/react-native/cloudEventsDispatcher.d.ts +15 -0
  50. package/dist/react-native/cloudEventsDispatcher.d.ts.map +1 -0
  51. package/dist/react-native/cloudEventsDispatcher.js +411 -0
  52. package/dist/react-native/cloudEventsDispatcher.js.map +1 -0
  53. package/dist/react-native/cloudEventsProtocols.d.ts +411 -0
  54. package/dist/react-native/cloudEventsProtocols.d.ts.map +1 -0
  55. package/dist/react-native/cloudEventsProtocols.js +4 -0
  56. package/dist/react-native/cloudEventsProtocols.js.map +1 -0
  57. package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts +180 -0
  58. package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts.map +1 -0
  59. package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.js +183 -0
  60. package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.js.map +1 -0
  61. package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts +31 -0
  62. package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts.map +1 -0
  63. package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js +34 -0
  64. package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js.map +1 -0
  65. package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts +112 -0
  66. package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts.map +1 -0
  67. package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js +115 -0
  68. package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js.map +1 -0
  69. package/dist/react-native/index.d.ts +6 -0
  70. package/dist/react-native/index.d.ts.map +1 -0
  71. package/dist/react-native/index.js +8 -0
  72. package/dist/react-native/index.js.map +1 -0
  73. package/dist/react-native/logger.d.ts +7 -0
  74. package/dist/react-native/logger.d.ts.map +1 -0
  75. package/dist/react-native/logger.js +10 -0
  76. package/dist/react-native/logger.js.map +1 -0
  77. package/dist/react-native/package.json +3 -0
  78. package/dist/react-native/utils.d.ts +6 -0
  79. package/dist/react-native/utils.d.ts.map +1 -0
  80. package/dist/react-native/utils.js +53 -0
  81. package/dist/react-native/utils.js.map +1 -0
  82. package/dist/react-native/webPubSubEventHandler.d.ts +46 -0
  83. package/dist/react-native/webPubSubEventHandler.d.ts.map +1 -0
  84. package/dist/react-native/webPubSubEventHandler.js +73 -0
  85. package/dist/react-native/webPubSubEventHandler.js.map +1 -0
  86. package/package.json +33 -17
package/README.md CHANGED
@@ -34,10 +34,10 @@ npm install @azure/web-pubsub-express
34
34
 
35
35
  ### 2. Create a `WebPubSubEventHandler`
36
36
 
37
- ```js
38
- const express = require("express");
37
+ ```ts snippet:ReadmeSampleCreateClient
38
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
39
+ import express from "express";
39
40
 
40
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
41
41
  const handler = new WebPubSubEventHandler("chat");
42
42
 
43
43
  const app = express();
@@ -79,10 +79,10 @@ Event handler contains the logic to handle the client events. Event handler need
79
79
 
80
80
  ### Handle the `connect` request and assign `<userId>`
81
81
 
82
- ```js
83
- const express = require("express");
82
+ ```ts snippet:ReadmeSampleConnect
83
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
84
+ import express from "express";
84
85
 
85
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
86
86
  const handler = new WebPubSubEventHandler("chat", {
87
87
  handleConnect: (req, res) => {
88
88
  // auth the connection and set the userId of the connection
@@ -104,10 +104,10 @@ app.listen(3000, () =>
104
104
 
105
105
  ### Handle the `connect` request and reject the connection if auth failed
106
106
 
107
- ```js
108
- const express = require("express");
107
+ ```ts snippet:ReadmeSampleConnectAndReject
108
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
109
+ import express from "express";
109
110
 
110
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
111
111
  const handler = new WebPubSubEventHandler("chat", {
112
112
  handleConnect: (req, res) => {
113
113
  // auth the connection and reject the connection if auth failed
@@ -129,10 +129,10 @@ app.listen(3000, () =>
129
129
 
130
130
  ### Handle the `connected` request
131
131
 
132
- ```js
133
- const express = require("express");
132
+ ```ts snippet:ReadmeSampleConnected
133
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
134
+ import express from "express";
134
135
 
135
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
136
136
  const handler = new WebPubSubEventHandler("chat", {
137
137
  onConnected: (connectedRequest) => {
138
138
  // Your onConnected logic goes here
@@ -151,10 +151,10 @@ app.listen(3000, () =>
151
151
 
152
152
  ### Handle the `onDisconnected` request
153
153
 
154
- ```js
155
- const express = require("express");
154
+ ```ts snippet:ReadmeSampleDisconnected
155
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
156
+ import express from "express";
156
157
 
157
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
158
158
  const handler = new WebPubSubEventHandler("chat", {
159
159
  onDisconnected: (disconnectedRequest) => {
160
160
  // Your onDisconnected logic goes here
@@ -173,14 +173,15 @@ app.listen(3000, () =>
173
173
 
174
174
  ### Handle the `connect` request for mqtt and assign `<userId>` and `<mqtt>` properties
175
175
 
176
- ```js
177
- const express = require("express");
176
+ ```ts snippet:ReadmeSampleConnectMqtt
177
+ import { WebPubSubEventHandler, MqttConnectRequest } from "@azure/web-pubsub-express";
178
+ import express from "express";
178
179
 
179
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
180
180
  const handler = new WebPubSubEventHandler("chat", {
181
181
  handleConnect: (req, res) => {
182
- if (req.context.clientProtocol === "mqtt") { // return mqtt response when request is of MQTT kind
183
- // get connect request as mqtt request and print it
182
+ if (req.context.clientProtocol === "mqtt") {
183
+ // return mqtt response when request is of MQTT kind
184
+ // get connect request as mqtt request and print it
184
185
  const mqttRequest = req as MqttConnectRequest;
185
186
  console.log(mqttRequest);
186
187
 
@@ -195,7 +196,7 @@ const handler = new WebPubSubEventHandler("chat", {
195
196
  });
196
197
  }
197
198
  },
198
- allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
199
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"],
199
200
  });
200
201
 
201
202
  const app = express();
@@ -203,20 +204,21 @@ const app = express();
203
204
  app.use(handler.getMiddleware());
204
205
 
205
206
  app.listen(3000, () =>
206
- console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
207
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`),
207
208
  );
208
209
  ```
209
210
 
210
211
  ### Handle the `connect` request for mqtt and reject the connection if auth failed
211
212
 
212
- ```js
213
- const express = require("express");
213
+ ```ts snippet:ReadmeSampleConnectMqttAndReject
214
+ import { WebPubSubEventHandler, MqttConnectRequest } from "@azure/web-pubsub-express";
215
+ import express from "express";
214
216
 
215
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
216
217
  const handler = new WebPubSubEventHandler("chat", {
217
218
  handleConnect: (req, res) => {
218
219
  // auth the connection and reject the connection if auth failed
219
- if (req.context.clientProtocol === "mqtt") { // return mqtt error response when request is of MQTT kind
220
+ if (req.context.clientProtocol === "mqtt") {
221
+ // return mqtt error response when request is of MQTT kind
220
222
  // get connect request as mqtt request and print it
221
223
  const mqttRequest = req as MqttConnectRequest;
222
224
  console.log(mqttRequest);
@@ -228,7 +230,7 @@ const handler = new WebPubSubEventHandler("chat", {
228
230
  // res.failWith({ mqtt: { code: MqttV500ConnectReasonCode.NotAuthorized } });
229
231
  } else res.success();
230
232
  },
231
- allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
233
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"],
232
234
  });
233
235
 
234
236
  const app = express();
@@ -236,16 +238,16 @@ const app = express();
236
238
  app.use(handler.getMiddleware());
237
239
 
238
240
  app.listen(3000, () =>
239
- console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
241
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`),
240
242
  );
241
243
  ```
242
244
 
243
245
  ### Handle the `onDisconnected` for mqtt request
244
246
 
245
- ```js
246
- const express = require("express");
247
+ ```ts snippet:ReadmeSampleDisconnectedMqtt
248
+ import { WebPubSubEventHandler, MqttDisconnectedRequest } from "@azure/web-pubsub-express";
249
+ import express from "express";
247
250
 
248
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
249
251
  const handler = new WebPubSubEventHandler("chat", {
250
252
  onDisconnected: (disconnectedRequest) => {
251
253
  if (disconnectedRequest.context.clientProtocol === "mqtt") {
@@ -258,7 +260,7 @@ const handler = new WebPubSubEventHandler("chat", {
258
260
  // Your onDisconnected logic goes here
259
261
  }
260
262
  },
261
- allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
263
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"],
262
264
  });
263
265
 
264
266
  const app = express();
@@ -266,16 +268,16 @@ const app = express();
266
268
  app.use(handler.getMiddleware());
267
269
 
268
270
  app.listen(3000, () =>
269
- console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
271
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`),
270
272
  );
271
273
  ```
272
274
 
273
275
  ### Only allow specified endpoints
274
276
 
275
- ```js
276
- const express = require("express");
277
+ ```ts snippet:ReadmeSampleAllowedEndpoints
278
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
279
+ import express from "express";
277
280
 
278
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
279
281
  const handler = new WebPubSubEventHandler("chat", {
280
282
  allowedEndpoints: [
281
283
  "https://<yourAllowedService1>.webpubsub.azure.com",
@@ -294,10 +296,10 @@ app.listen(3000, () =>
294
296
 
295
297
  ### Set custom event handler path
296
298
 
297
- ```js
298
- const express = require("express");
299
+ ```ts snippet:ReadmeSampleCustomPath
300
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
301
+ import express from "express";
299
302
 
300
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
301
303
  const handler = new WebPubSubEventHandler("chat", {
302
304
  path: "/customPath1",
303
305
  });
@@ -314,10 +316,9 @@ app.listen(3000, () =>
314
316
 
315
317
  ### Set and read connection state
316
318
 
317
- ```js
318
- const express = require("express");
319
-
320
- const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
319
+ ```ts snippet:ReadmeSampleState
320
+ import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
321
+ import express from "express";
321
322
 
322
323
  const handler = new WebPubSubEventHandler("chat", {
323
324
  handleConnect(req, res) {
@@ -347,14 +348,20 @@ app.listen(3000, () =>
347
348
 
348
349
  ### Enable logs
349
350
 
350
- You can set the following environment variable to get the debug logs when using this library.
351
-
352
- - Getting debug logs from the SignalR client library
351
+ Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`.
353
352
 
354
353
  ```bash
355
354
  export AZURE_LOG_LEVEL=verbose
356
355
  ```
357
356
 
357
+ Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`:
358
+
359
+ ```ts snippet:SetLogLevel
360
+ import { setLogLevel } from "@azure/logger";
361
+
362
+ setLogLevel("info");
363
+ ```
364
+
358
365
  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).
359
366
 
360
367
  ### Live Trace
@@ -0,0 +1,15 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { WebPubSubEventHandlerOptions } from "./cloudEventsProtocols.js";
3
+ /**
4
+ * @internal
5
+ */
6
+ export declare class CloudEventsDispatcher {
7
+ private hub;
8
+ private eventHandler?;
9
+ private readonly _allowAll;
10
+ private readonly _allowedOrigins;
11
+ constructor(hub: string, eventHandler?: WebPubSubEventHandlerOptions | undefined);
12
+ handlePreflight(req: IncomingMessage, res: ServerResponse): boolean;
13
+ handleRequest(request: IncomingMessage, response: ServerResponse): Promise<boolean>;
14
+ }
15
+ //# sourceMappingURL=cloudEventsDispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudEventsDispatcher.d.ts","sourceRoot":"","sources":["../../src/cloudEventsDispatcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EASV,4BAA4B,EAM7B,MAAM,2BAA2B,CAAC;AAuTnC;;GAEG;AACH,qBAAa,qBAAqB;IAI9B,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,YAAY,CAAC;IAJvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;gBAE3C,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,4BAA4B,YAAA;IAa9C,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO;IAoB7D,aAAa,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;CA2GjG"}
@@ -0,0 +1,411 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import * as utils from "./utils.js";
4
+ import { URL } from "node:url";
5
+ import { logger } from "./logger.js";
6
+ import { MqttV311ConnectReturnCode } from "./enum/MqttErrorCodes/mqttV311ConnectReturnCode.js";
7
+ import { MqttV500ConnectReasonCode } from "./enum/MqttErrorCodes/mqttV500ConnectReasonCode.js";
8
+ var EventType;
9
+ (function (EventType) {
10
+ EventType[EventType["Connect"] = 0] = "Connect";
11
+ EventType[EventType["Connected"] = 1] = "Connected";
12
+ EventType[EventType["Disconnected"] = 2] = "Disconnected";
13
+ EventType[EventType["UserEvent"] = 3] = "UserEvent";
14
+ })(EventType || (EventType = {}));
15
+ function getConnectResponseHandler(connectRequest, response) {
16
+ const states = connectRequest.context.states;
17
+ let modified = false;
18
+ const handler = {
19
+ setState(name, value) {
20
+ states[name] = value;
21
+ modified = true;
22
+ },
23
+ success(res) {
24
+ if (modified) {
25
+ response.setHeader("ce-connectionState", utils.toBase64JsonString(states));
26
+ }
27
+ if (res === undefined) {
28
+ response.statusCode = 204;
29
+ response.end();
30
+ }
31
+ else {
32
+ response.statusCode = 200;
33
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
34
+ response.end(JSON.stringify(res));
35
+ }
36
+ },
37
+ fail(code, detail) {
38
+ handleConnectErrorResponse(connectRequest, response, code, detail);
39
+ },
40
+ failWith(res) {
41
+ if ("mqtt" in res) {
42
+ response.statusCode = getStatusCodeFromMqttConnectCode(res.mqtt.code);
43
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
44
+ response.end(JSON.stringify(res));
45
+ }
46
+ else {
47
+ handleConnectErrorResponse(connectRequest, response, res.code, res.detail);
48
+ }
49
+ },
50
+ };
51
+ return handler;
52
+ }
53
+ function getUserEventResponseHandler(userRequest, response) {
54
+ const states = userRequest.context.states;
55
+ let modified = false;
56
+ const handler = {
57
+ setState(name, value) {
58
+ modified = true;
59
+ states[name] = value;
60
+ },
61
+ success(data, dataType) {
62
+ response.statusCode = 200;
63
+ if (modified) {
64
+ response.setHeader("ce-connectionState", utils.toBase64JsonString(states));
65
+ }
66
+ switch (dataType) {
67
+ case "json":
68
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
69
+ break;
70
+ case "text":
71
+ response.setHeader("Content-Type", "text/plain; charset=utf-8");
72
+ break;
73
+ default:
74
+ response.setHeader("Content-Type", "application/octet-stream");
75
+ break;
76
+ }
77
+ response.end(data !== null && data !== void 0 ? data : "");
78
+ },
79
+ fail(code, detail) {
80
+ response.statusCode = code;
81
+ response.end(detail !== null && detail !== void 0 ? detail : "");
82
+ },
83
+ };
84
+ return handler;
85
+ }
86
+ function getContext(request, origin) {
87
+ const baseContext = {
88
+ signature: utils.getHttpHeader(request, "ce-signature"),
89
+ userId: utils.getHttpHeader(request, "ce-userid"),
90
+ hub: utils.getHttpHeader(request, "ce-hub"),
91
+ connectionId: utils.getHttpHeader(request, "ce-connectionid"),
92
+ eventName: utils.getHttpHeader(request, "ce-eventname"),
93
+ origin: origin,
94
+ states: utils.fromBase64JsonString(utils.getHttpHeader(request, "ce-connectionstate")),
95
+ clientProtocol: "default",
96
+ };
97
+ if (isMqttRequest(request)) {
98
+ const mqttProperties = {
99
+ physicalConnectionId: utils.getHttpHeader(request, "ce-physicalConnectionId"),
100
+ sessionId: utils.getHttpHeader(request, "ce-sessionId"),
101
+ };
102
+ return Object.assign(Object.assign({}, baseContext), { clientProtocol: "mqtt", mqtt: mqttProperties });
103
+ }
104
+ else {
105
+ return baseContext;
106
+ }
107
+ }
108
+ function tryGetWebPubSubEvent(req) {
109
+ // check ce-type to see if it is a valid WebPubSub CloudEvent request
110
+ const prefix = "azure.webpubsub.";
111
+ const connect = "azure.webpubsub.sys.connect";
112
+ const connected = "azure.webpubsub.sys.connected";
113
+ const disconnectd = "azure.webpubsub.sys.disconnected";
114
+ const userPrefix = "azure.webpubsub.user.";
115
+ const type = utils.getHttpHeader(req, "ce-type");
116
+ if (!(type === null || type === void 0 ? void 0 : type.startsWith(prefix))) {
117
+ return undefined;
118
+ }
119
+ if (type.startsWith(userPrefix)) {
120
+ return EventType.UserEvent;
121
+ }
122
+ switch (type) {
123
+ case connect:
124
+ return EventType.Connect;
125
+ case connected:
126
+ return EventType.Connected;
127
+ case disconnectd:
128
+ return EventType.Disconnected;
129
+ default:
130
+ return undefined;
131
+ }
132
+ }
133
+ function getStatusCodeFromMqttConnectCode(mqttConnectCode) {
134
+ if (mqttConnectCode < 0x80) {
135
+ switch (mqttConnectCode) {
136
+ case MqttV311ConnectReturnCode.UnacceptableProtocolVersion:
137
+ case MqttV311ConnectReturnCode.IdentifierRejected:
138
+ return 400; // BadRequest
139
+ case MqttV311ConnectReturnCode.ServerUnavailable:
140
+ return 503; // ServiceUnavailable
141
+ case MqttV311ConnectReturnCode.BadUsernameOrPassword:
142
+ case MqttV311ConnectReturnCode.NotAuthorized:
143
+ return 401; // Unauthorized
144
+ default:
145
+ logger.warning(`Invalid MQTT connect return code: ${mqttConnectCode}.`);
146
+ return 500; // InternalServerError
147
+ }
148
+ }
149
+ else {
150
+ switch (mqttConnectCode) {
151
+ case MqttV500ConnectReasonCode.NotAuthorized:
152
+ case MqttV500ConnectReasonCode.BadUserNameOrPassword:
153
+ return 401; // Unauthorized
154
+ case MqttV500ConnectReasonCode.ClientIdentifierNotValid:
155
+ case MqttV500ConnectReasonCode.MalformedPacket:
156
+ case MqttV500ConnectReasonCode.UnsupportedProtocolVersion:
157
+ case MqttV500ConnectReasonCode.BadAuthenticationMethod:
158
+ case MqttV500ConnectReasonCode.TopicNameInvalid:
159
+ case MqttV500ConnectReasonCode.PayloadFormatInvalid:
160
+ case MqttV500ConnectReasonCode.ImplementationSpecificError:
161
+ case MqttV500ConnectReasonCode.PacketTooLarge:
162
+ case MqttV500ConnectReasonCode.RetainNotSupported:
163
+ case MqttV500ConnectReasonCode.QosNotSupported:
164
+ return 400; // BadRequest
165
+ case MqttV500ConnectReasonCode.QuotaExceeded:
166
+ case MqttV500ConnectReasonCode.ConnectionRateExceeded:
167
+ return 429; // TooManyRequests
168
+ case MqttV500ConnectReasonCode.Banned:
169
+ return 403; // Forbidden
170
+ case MqttV500ConnectReasonCode.UseAnotherServer:
171
+ case MqttV500ConnectReasonCode.ServerMoved:
172
+ case MqttV500ConnectReasonCode.ServerUnavailable:
173
+ case MqttV500ConnectReasonCode.ServerBusy:
174
+ case MqttV500ConnectReasonCode.UnspecifiedError:
175
+ return 500; // InternalServerError
176
+ default:
177
+ logger.warning(`Invalid MQTT connect return code: ${mqttConnectCode}.`);
178
+ return 500; // InternalServerError
179
+ }
180
+ }
181
+ }
182
+ function getMqttConnectCodeFromStatusCode(statusCode, protocolVersion) {
183
+ if (protocolVersion === 4) {
184
+ switch (statusCode) {
185
+ case 400:
186
+ return MqttV311ConnectReturnCode.BadUsernameOrPassword;
187
+ case 401:
188
+ return MqttV311ConnectReturnCode.NotAuthorized;
189
+ case 500:
190
+ return MqttV311ConnectReturnCode.ServerUnavailable;
191
+ default:
192
+ logger.warning(`Unsupported HTTP Status Code: ${statusCode}.`);
193
+ return MqttV311ConnectReturnCode.ServerUnavailable;
194
+ }
195
+ }
196
+ else if (protocolVersion === 5) {
197
+ switch (statusCode) {
198
+ case 400:
199
+ return MqttV500ConnectReasonCode.BadUserNameOrPassword;
200
+ case 401:
201
+ return MqttV500ConnectReasonCode.NotAuthorized;
202
+ case 500:
203
+ return MqttV500ConnectReasonCode.UnspecifiedError;
204
+ default:
205
+ logger.warning(`Unsupported HTTP Status Code: ${statusCode}.`);
206
+ return MqttV500ConnectReasonCode.UnspecifiedError;
207
+ }
208
+ }
209
+ else {
210
+ logger.warning(`Invalid MQTT protocol version: ${protocolVersion}.`);
211
+ return MqttV311ConnectReturnCode.UnacceptableProtocolVersion;
212
+ }
213
+ }
214
+ function handleConnectErrorResponse(connectRequest, response, code, detail) {
215
+ const isMqttReq = connectRequest.context.clientProtocol === "mqtt";
216
+ if (isMqttReq) {
217
+ const protocolVersion = connectRequest.mqtt.protocolVersion;
218
+ const mqttErrorResponse = {
219
+ mqtt: {
220
+ code: getMqttConnectCodeFromStatusCode(code, protocolVersion),
221
+ reason: detail,
222
+ },
223
+ };
224
+ response.statusCode = code;
225
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
226
+ response.end(JSON.stringify(mqttErrorResponse));
227
+ }
228
+ else {
229
+ response.statusCode = code;
230
+ response.end(detail !== null && detail !== void 0 ? detail : "");
231
+ }
232
+ }
233
+ function isWebPubSubRequest(req) {
234
+ return utils.getHttpHeader(req, "ce-awpsversion") !== undefined;
235
+ }
236
+ function isMqttRequest(req) {
237
+ const subprotocol = utils.getHttpHeader(req, "ce-subprotocol");
238
+ const physicalConnectionId = utils.getHttpHeader(req, "ce-physicalConnectionId");
239
+ return (subprotocol !== undefined &&
240
+ subprotocol.toLowerCase().includes("mqtt") &&
241
+ physicalConnectionId !== undefined);
242
+ }
243
+ async function readUserEventRequest(request, origin) {
244
+ const contentTypeheader = utils.getHttpHeader(request, "content-type");
245
+ if (contentTypeheader === undefined) {
246
+ return undefined;
247
+ }
248
+ const contentType = contentTypeheader.split(";")[0].trim();
249
+ switch (contentType) {
250
+ case "application/octet-stream":
251
+ return {
252
+ context: getContext(request, origin),
253
+ data: await utils.readRequestBody(request),
254
+ dataType: "binary",
255
+ };
256
+ case "application/json":
257
+ return {
258
+ context: getContext(request, origin),
259
+ data: JSON.parse((await utils.readRequestBody(request)).toString()),
260
+ dataType: "json",
261
+ };
262
+ case "text/plain":
263
+ return {
264
+ context: getContext(request, origin),
265
+ data: (await utils.readRequestBody(request)).toString(),
266
+ dataType: "text",
267
+ };
268
+ default:
269
+ return undefined;
270
+ }
271
+ }
272
+ async function readSystemEventRequest(request, origin) {
273
+ const body = (await utils.readRequestBody(request)).toString();
274
+ const parsedRequest = JSON.parse(body);
275
+ parsedRequest.context = getContext(request, origin);
276
+ return parsedRequest;
277
+ }
278
+ /**
279
+ * @internal
280
+ */
281
+ export class CloudEventsDispatcher {
282
+ constructor(hub, eventHandler) {
283
+ this.hub = hub;
284
+ this.eventHandler = eventHandler;
285
+ this._allowAll = true;
286
+ this._allowedOrigins = [];
287
+ if (Array.isArray(eventHandler)) {
288
+ throw new Error("Unexpected WebPubSubEventHandlerOptions");
289
+ }
290
+ if ((eventHandler === null || eventHandler === void 0 ? void 0 : eventHandler.allowedEndpoints) !== undefined) {
291
+ this._allowedOrigins = eventHandler.allowedEndpoints.map((endpoint) => new URL(endpoint).host.toLowerCase());
292
+ this._allowAll = false;
293
+ }
294
+ }
295
+ handlePreflight(req, res) {
296
+ if (!isWebPubSubRequest(req)) {
297
+ return false;
298
+ }
299
+ const origin = utils.getHttpHeader(req, "webhook-request-origin");
300
+ if (origin === undefined) {
301
+ logger.warning("Expecting webhook-request-origin header.");
302
+ res.statusCode = 400;
303
+ }
304
+ else if (this._allowAll) {
305
+ res.setHeader("WebHook-Allowed-Origin", "*");
306
+ }
307
+ else {
308
+ // service to do the check
309
+ res.setHeader("WebHook-Allowed-Origin", this._allowedOrigins);
310
+ }
311
+ res.end();
312
+ return true;
313
+ }
314
+ async handleRequest(request, response) {
315
+ var _a, _b, _c, _d;
316
+ if (!isWebPubSubRequest(request)) {
317
+ return false;
318
+ }
319
+ // check if it is a valid WebPubSub cloud events
320
+ const origin = utils.getHttpHeader(request, "webhook-request-origin");
321
+ if (origin === undefined) {
322
+ return false;
323
+ }
324
+ const eventType = tryGetWebPubSubEvent(request);
325
+ if (eventType === undefined) {
326
+ return false;
327
+ }
328
+ // check if hub matches
329
+ const hub = utils.getHttpHeader(request, "ce-hub");
330
+ if ((hub === null || hub === void 0 ? void 0 : hub.toUpperCase()) !== this.hub.toUpperCase()) {
331
+ return false;
332
+ }
333
+ const isMqtt = isMqttRequest(request);
334
+ // No need to read body if handler is not specified
335
+ switch (eventType) {
336
+ case EventType.Connect:
337
+ if (!((_a = this.eventHandler) === null || _a === void 0 ? void 0 : _a.handleConnect)) {
338
+ if (isMqtt)
339
+ response.statusCode = 204;
340
+ response.end();
341
+ return true;
342
+ }
343
+ break;
344
+ case EventType.Connected:
345
+ if (!((_b = this.eventHandler) === null || _b === void 0 ? void 0 : _b.onConnected)) {
346
+ response.end();
347
+ return true;
348
+ }
349
+ break;
350
+ case EventType.Disconnected:
351
+ if (!((_c = this.eventHandler) === null || _c === void 0 ? void 0 : _c.onDisconnected)) {
352
+ response.end();
353
+ return true;
354
+ }
355
+ break;
356
+ case EventType.UserEvent:
357
+ if (!((_d = this.eventHandler) === null || _d === void 0 ? void 0 : _d.handleUserEvent)) {
358
+ response.end();
359
+ return true;
360
+ }
361
+ break;
362
+ default:
363
+ logger.warning(`Unknown EventType ${eventType}`);
364
+ return false;
365
+ }
366
+ switch (eventType) {
367
+ case EventType.Connect: {
368
+ const connectRequest = isMqtt
369
+ ? await readSystemEventRequest(request, origin)
370
+ : await readSystemEventRequest(request, origin);
371
+ // service passes out query property, assign it to queries
372
+ connectRequest.queries = connectRequest.query;
373
+ logger.verbose(connectRequest);
374
+ this.eventHandler.handleConnect(connectRequest, getConnectResponseHandler(connectRequest, response));
375
+ return true;
376
+ }
377
+ case EventType.Connected: {
378
+ // for unblocking events, we responds to the service as early as possible
379
+ response.end();
380
+ const connectedRequest = await readSystemEventRequest(request, origin);
381
+ logger.verbose(connectedRequest);
382
+ this.eventHandler.onConnected(connectedRequest);
383
+ return true;
384
+ }
385
+ case EventType.Disconnected: {
386
+ // for unblocking events, we responds to the service as early as possible
387
+ response.end();
388
+ const disconnectedRequest = isMqtt
389
+ ? await readSystemEventRequest(request, origin)
390
+ : await readSystemEventRequest(request, origin);
391
+ logger.verbose(disconnectedRequest);
392
+ this.eventHandler.onDisconnected(disconnectedRequest);
393
+ return true;
394
+ }
395
+ case EventType.UserEvent: {
396
+ const userRequest = await readUserEventRequest(request, origin);
397
+ if (userRequest === undefined) {
398
+ logger.warning(`Unsupported content type ${utils.getHttpHeader(request, "content-type")}`);
399
+ return false;
400
+ }
401
+ logger.verbose(userRequest);
402
+ this.eventHandler.handleUserEvent(userRequest, getUserEventResponseHandler(userRequest, response));
403
+ return true;
404
+ }
405
+ default:
406
+ logger.warning(`Unknown EventType ${eventType}`);
407
+ return false;
408
+ }
409
+ }
410
+ }
411
+ //# sourceMappingURL=cloudEventsDispatcher.js.map