@azure/web-pubsub-express 1.0.6-alpha.20240927.1 → 1.0.6-alpha.20241001.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.
Files changed (47) hide show
  1. package/README.md +165 -0
  2. package/dist/commonjs/cloudEventsDispatcher.d.ts.map +1 -1
  3. package/dist/commonjs/cloudEventsDispatcher.js +143 -8
  4. package/dist/commonjs/cloudEventsDispatcher.js.map +1 -1
  5. package/dist/commonjs/cloudEventsProtocols.d.ts +174 -1
  6. package/dist/commonjs/cloudEventsProtocols.d.ts.map +1 -1
  7. package/dist/commonjs/cloudEventsProtocols.js.map +1 -1
  8. package/dist/commonjs/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts +180 -0
  9. package/dist/commonjs/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts.map +1 -0
  10. package/dist/commonjs/enum/MqttErrorCodes/mqttDisconnectReasonCode.js +186 -0
  11. package/dist/commonjs/enum/MqttErrorCodes/mqttDisconnectReasonCode.js.map +1 -0
  12. package/dist/commonjs/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts +31 -0
  13. package/dist/commonjs/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts.map +1 -0
  14. package/dist/commonjs/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js +37 -0
  15. package/dist/commonjs/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js.map +1 -0
  16. package/dist/commonjs/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts +112 -0
  17. package/dist/commonjs/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts.map +1 -0
  18. package/dist/commonjs/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js +118 -0
  19. package/dist/commonjs/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js.map +1 -0
  20. package/dist/commonjs/index.d.ts +3 -0
  21. package/dist/commonjs/index.d.ts.map +1 -1
  22. package/dist/commonjs/index.js +473 -8
  23. package/dist/commonjs/index.js.map +1 -1
  24. package/dist/esm/cloudEventsDispatcher.d.ts.map +1 -1
  25. package/dist/esm/cloudEventsDispatcher.js +143 -8
  26. package/dist/esm/cloudEventsDispatcher.js.map +1 -1
  27. package/dist/esm/cloudEventsProtocols.d.ts +174 -1
  28. package/dist/esm/cloudEventsProtocols.d.ts.map +1 -1
  29. package/dist/esm/cloudEventsProtocols.js.map +1 -1
  30. package/dist/esm/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts +180 -0
  31. package/dist/esm/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts.map +1 -0
  32. package/dist/esm/enum/MqttErrorCodes/mqttDisconnectReasonCode.js +183 -0
  33. package/dist/esm/enum/MqttErrorCodes/mqttDisconnectReasonCode.js.map +1 -0
  34. package/dist/esm/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts +31 -0
  35. package/dist/esm/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts.map +1 -0
  36. package/dist/esm/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js +34 -0
  37. package/dist/esm/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js.map +1 -0
  38. package/dist/esm/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts +112 -0
  39. package/dist/esm/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts.map +1 -0
  40. package/dist/esm/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js +115 -0
  41. package/dist/esm/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js.map +1 -0
  42. package/dist/esm/index.d.ts +3 -0
  43. package/dist/esm/index.d.ts.map +1 -1
  44. package/dist/esm/index.js +3 -0
  45. package/dist/esm/index.js.map +1 -1
  46. package/dist/web-pubsub-express.d.ts +507 -1
  47. package/package.json +1 -1
package/README.md CHANGED
@@ -102,6 +102,171 @@ app.listen(3000, () =>
102
102
  );
103
103
  ```
104
104
 
105
+ ### Handle the `connect` request and reject the connection if auth failed
106
+ ```js
107
+ const express = require("express");
108
+
109
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
110
+ const handler = new WebPubSubEventHandler("chat", {
111
+ handleConnect: (req, res) => {
112
+ // auth the connection and reject the connection if auth failed
113
+ res.fail(401, "Unauthorized");
114
+ // the following method is also a valid approach
115
+ // res.failWith({ code: 401, detail: "Unauthorized" });
116
+ },
117
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
118
+ });
119
+
120
+ const app = express();
121
+
122
+ app.use(handler.getMiddleware());
123
+
124
+ app.listen(3000, () =>
125
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
126
+ );
127
+ ```
128
+
129
+ ### Handle the `connected` request
130
+
131
+ ```js
132
+ const express = require("express");
133
+
134
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
135
+ const handler = new WebPubSubEventHandler("chat", {
136
+ onConnected: (connectedRequest) => {
137
+ // Your onConnected logic goes here
138
+ },
139
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
140
+ });
141
+
142
+ const app = express();
143
+
144
+ app.use(handler.getMiddleware());
145
+
146
+ app.listen(3000, () =>
147
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
148
+ );
149
+ ```
150
+
151
+ ### Handle the `onDisconnected` request
152
+
153
+ ```js
154
+ const express = require("express");
155
+
156
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
157
+ const handler = new WebPubSubEventHandler("chat", {
158
+ onDisconnected: (disconnectedRequest) => {
159
+ // Your onDisconnected logic goes here
160
+ },
161
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
162
+ });
163
+
164
+ const app = express();
165
+
166
+ app.use(handler.getMiddleware());
167
+
168
+ app.listen(3000, () =>
169
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
170
+ );
171
+ ```
172
+
173
+ ### Handle the `connect` request for mqtt and assign `<userId>` and `<mqtt>` properties
174
+ ```js
175
+ const express = require("express");
176
+
177
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
178
+ const handler = new WebPubSubEventHandler("chat", {
179
+ handleConnect: (req, res) => {
180
+ if (req.context.clientProtocol === "mqtt") { // return mqtt response when request is of MQTT kind
181
+ // get connect request as mqtt request and print it
182
+ const mqttRequest = req as MqttConnectRequest;
183
+ console.log(mqttRequest);
184
+
185
+ // auth the connection and return mqtt response
186
+ res.success({
187
+ userId: "user1",
188
+ mqtt: { userProperties: [{ name: "a", value: "b" }] },
189
+ });
190
+ } else {
191
+ res.success({
192
+ userId: "user1",
193
+ });
194
+ }
195
+ },
196
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
197
+ });
198
+
199
+ const app = express();
200
+
201
+ app.use(handler.getMiddleware());
202
+
203
+ app.listen(3000, () =>
204
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
205
+ );
206
+ ```
207
+
208
+ ### Handle the `connect` request for mqtt and reject the connection if auth failed
209
+ ```js
210
+ const express = require("express");
211
+
212
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
213
+ const handler = new WebPubSubEventHandler("chat", {
214
+ handleConnect: (req, res) => {
215
+ // auth the connection and reject the connection if auth failed
216
+ if (req.context.clientProtocol === "mqtt") { // return mqtt error response when request is of MQTT kind
217
+ // get connect request as mqtt request and print it
218
+ const mqttRequest = req as MqttConnectRequest;
219
+ console.log(mqttRequest);
220
+
221
+ // auth the connection and return mqtt failure response
222
+ res.fail(401, "Not Authorized");
223
+
224
+ // Or use below method for more fine-grained control over the MQTT return code
225
+ // res.failWith({ mqtt: { code: MqttV500ConnectReasonCode.NotAuthorized } });
226
+ } else res.success();
227
+ },
228
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
229
+ });
230
+
231
+ const app = express();
232
+
233
+ app.use(handler.getMiddleware());
234
+
235
+ app.listen(3000, () =>
236
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
237
+ );
238
+ ```
239
+
240
+ ### Handle the `onDisconnected` for mqtt request
241
+
242
+ ```js
243
+ const express = require("express");
244
+
245
+ const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
246
+ const handler = new WebPubSubEventHandler("chat", {
247
+ onDisconnected: (disconnectedRequest) => {
248
+ if (disconnectedRequest.context.clientProtocol === "mqtt") {
249
+ // get disconnect request as mqtt request and print it
250
+ const mqttRequest = disconnectedRequest as MqttDisconnectedRequest;
251
+ console.log(mqttRequest.mqtt);
252
+ // Your onDisconnected logic goes here
253
+ } else {
254
+ console.log(disconnectedRequest);
255
+ // Your onDisconnected logic goes here
256
+ }
257
+ },
258
+ allowedEndpoints: ["https://<yourAllowedService>.webpubsub.azure.com"]
259
+ });
260
+
261
+ const app = express();
262
+
263
+ app.use(handler.getMiddleware());
264
+
265
+ app.listen(3000, () =>
266
+ console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
267
+ );
268
+ ```
269
+
105
270
  ### Only allow specified endpoints
106
271
 
107
272
  ```js
@@ -1 +1 @@
1
- {"version":3,"file":"cloudEventsDispatcher.d.ts","sourceRoot":"","sources":["../../src/cloudEventsDispatcher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAI5D,OAAO,KAAK,EASV,4BAA4B,EAC7B,MAAM,2BAA2B,CAAC;AAyKnC;;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;CAyGjG"}
1
+ {"version":3,"file":"cloudEventsDispatcher.d.ts","sourceRoot":"","sources":["../../src/cloudEventsDispatcher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAI5D,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"}
@@ -7,6 +7,8 @@ const tslib_1 = require("tslib");
7
7
  const utils = tslib_1.__importStar(require("./utils.js"));
8
8
  const node_url_1 = require("node:url");
9
9
  const logger_js_1 = require("./logger.js");
10
+ const mqttV311ConnectReturnCode_js_1 = require("./enum/MqttErrorCodes/mqttV311ConnectReturnCode.js");
11
+ const mqttV500ConnectReasonCode_js_1 = require("./enum/MqttErrorCodes/mqttV500ConnectReasonCode.js");
10
12
  var EventType;
11
13
  (function (EventType) {
12
14
  EventType[EventType["Connect"] = 0] = "Connect";
@@ -23,21 +25,31 @@ function getConnectResponseHandler(connectRequest, response) {
23
25
  modified = true;
24
26
  },
25
27
  success(res) {
26
- response.statusCode = 200;
27
28
  if (modified) {
28
29
  response.setHeader("ce-connectionState", utils.toBase64JsonString(states));
29
30
  }
30
31
  if (res === undefined) {
32
+ response.statusCode = 204;
31
33
  response.end();
32
34
  }
33
35
  else {
36
+ response.statusCode = 200;
34
37
  response.setHeader("Content-Type", "application/json; charset=utf-8");
35
38
  response.end(JSON.stringify(res));
36
39
  }
37
40
  },
38
41
  fail(code, detail) {
39
- response.statusCode = code;
40
- response.end(detail !== null && detail !== void 0 ? detail : "");
42
+ handleConnectErrorResponse(connectRequest, response, code, detail);
43
+ },
44
+ failWith(res) {
45
+ if ("mqtt" in res) {
46
+ response.statusCode = getStatusCodeFromMqttConnectCode(res.mqtt.code);
47
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
48
+ response.end(JSON.stringify(res));
49
+ }
50
+ else {
51
+ handleConnectErrorResponse(connectRequest, response, res.code, res.detail);
52
+ }
41
53
  },
42
54
  };
43
55
  return handler;
@@ -76,7 +88,7 @@ function getUserEventResponseHandler(userRequest, response) {
76
88
  return handler;
77
89
  }
78
90
  function getContext(request, origin) {
79
- const context = {
91
+ const baseContext = {
80
92
  signature: utils.getHttpHeader(request, "ce-signature"),
81
93
  userId: utils.getHttpHeader(request, "ce-userid"),
82
94
  hub: utils.getHttpHeader(request, "ce-hub"),
@@ -84,9 +96,18 @@ function getContext(request, origin) {
84
96
  eventName: utils.getHttpHeader(request, "ce-eventname"),
85
97
  origin: origin,
86
98
  states: utils.fromBase64JsonString(utils.getHttpHeader(request, "ce-connectionstate")),
99
+ clientProtocol: "default",
87
100
  };
88
- // TODO: validation
89
- return context;
101
+ if (isMqttRequest(request)) {
102
+ const mqttProperties = {
103
+ physicalConnectionId: utils.getHttpHeader(request, "ce-physicalConnectionId"),
104
+ sessionId: utils.getHttpHeader(request, "ce-sessionId"),
105
+ };
106
+ return Object.assign(Object.assign({}, baseContext), { clientProtocol: "mqtt", mqtt: mqttProperties });
107
+ }
108
+ else {
109
+ return baseContext;
110
+ }
90
111
  }
91
112
  function tryGetWebPubSubEvent(req) {
92
113
  // check ce-type to see if it is a valid WebPubSub CloudEvent request
@@ -113,9 +134,116 @@ function tryGetWebPubSubEvent(req) {
113
134
  return undefined;
114
135
  }
115
136
  }
137
+ function getStatusCodeFromMqttConnectCode(mqttConnectCode) {
138
+ if (mqttConnectCode < 0x80) {
139
+ switch (mqttConnectCode) {
140
+ case mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.UnacceptableProtocolVersion:
141
+ case mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.IdentifierRejected:
142
+ return 400; // BadRequest
143
+ case mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.ServerUnavailable:
144
+ return 503; // ServiceUnavailable
145
+ case mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.BadUsernameOrPassword:
146
+ case mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.NotAuthorized:
147
+ return 401; // Unauthorized
148
+ default:
149
+ logger_js_1.logger.warning(`Invalid MQTT connect return code: ${mqttConnectCode}.`);
150
+ return 500; // InternalServerError
151
+ }
152
+ }
153
+ else {
154
+ switch (mqttConnectCode) {
155
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.NotAuthorized:
156
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.BadUserNameOrPassword:
157
+ return 401; // Unauthorized
158
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.ClientIdentifierNotValid:
159
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.MalformedPacket:
160
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.UnsupportedProtocolVersion:
161
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.BadAuthenticationMethod:
162
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.TopicNameInvalid:
163
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.PayloadFormatInvalid:
164
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.ImplementationSpecificError:
165
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.PacketTooLarge:
166
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.RetainNotSupported:
167
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.QosNotSupported:
168
+ return 400; // BadRequest
169
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.QuotaExceeded:
170
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.ConnectionRateExceeded:
171
+ return 429; // TooManyRequests
172
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.Banned:
173
+ return 403; // Forbidden
174
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.UseAnotherServer:
175
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.ServerMoved:
176
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.ServerUnavailable:
177
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.ServerBusy:
178
+ case mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.UnspecifiedError:
179
+ return 500; // InternalServerError
180
+ default:
181
+ logger_js_1.logger.warning(`Invalid MQTT connect return code: ${mqttConnectCode}.`);
182
+ return 500; // InternalServerError
183
+ }
184
+ }
185
+ }
186
+ function getMqttConnectCodeFromStatusCode(statusCode, protocolVersion) {
187
+ if (protocolVersion === 4) {
188
+ switch (statusCode) {
189
+ case 400:
190
+ return mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.BadUsernameOrPassword;
191
+ case 401:
192
+ return mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.NotAuthorized;
193
+ case 500:
194
+ return mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.ServerUnavailable;
195
+ default:
196
+ logger_js_1.logger.warning(`Unsupported HTTP Status Code: ${statusCode}.`);
197
+ return mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.ServerUnavailable;
198
+ }
199
+ }
200
+ else if (protocolVersion === 5) {
201
+ switch (statusCode) {
202
+ case 400:
203
+ return mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.BadUserNameOrPassword;
204
+ case 401:
205
+ return mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.NotAuthorized;
206
+ case 500:
207
+ return mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.UnspecifiedError;
208
+ default:
209
+ logger_js_1.logger.warning(`Unsupported HTTP Status Code: ${statusCode}.`);
210
+ return mqttV500ConnectReasonCode_js_1.MqttV500ConnectReasonCode.UnspecifiedError;
211
+ }
212
+ }
213
+ else {
214
+ logger_js_1.logger.warning(`Invalid MQTT protocol version: ${protocolVersion}.`);
215
+ return mqttV311ConnectReturnCode_js_1.MqttV311ConnectReturnCode.UnacceptableProtocolVersion;
216
+ }
217
+ }
218
+ function handleConnectErrorResponse(connectRequest, response, code, detail) {
219
+ const isMqttReq = connectRequest.context.clientProtocol === "mqtt";
220
+ if (isMqttReq) {
221
+ const protocolVersion = connectRequest.mqtt.protocolVersion;
222
+ const mqttErrorResponse = {
223
+ mqtt: {
224
+ code: getMqttConnectCodeFromStatusCode(code, protocolVersion),
225
+ reason: detail,
226
+ },
227
+ };
228
+ response.statusCode = code;
229
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
230
+ response.end(JSON.stringify(mqttErrorResponse));
231
+ }
232
+ else {
233
+ response.statusCode = code;
234
+ response.end(detail !== null && detail !== void 0 ? detail : "");
235
+ }
236
+ }
116
237
  function isWebPubSubRequest(req) {
117
238
  return utils.getHttpHeader(req, "ce-awpsversion") !== undefined;
118
239
  }
240
+ function isMqttRequest(req) {
241
+ const subprotocol = utils.getHttpHeader(req, "ce-subprotocol");
242
+ const physicalConnectionId = utils.getHttpHeader(req, "ce-physicalConnectionId");
243
+ return (subprotocol !== undefined &&
244
+ subprotocol.toLowerCase().includes("mqtt") &&
245
+ physicalConnectionId !== undefined);
246
+ }
119
247
  async function readUserEventRequest(request, origin) {
120
248
  const contentTypeheader = utils.getHttpHeader(request, "content-type");
121
249
  if (contentTypeheader === undefined) {
@@ -206,10 +334,13 @@ class CloudEventsDispatcher {
206
334
  if ((hub === null || hub === void 0 ? void 0 : hub.toUpperCase()) !== this.hub.toUpperCase()) {
207
335
  return false;
208
336
  }
337
+ const isMqtt = isMqttRequest(request);
209
338
  // No need to read body if handler is not specified
210
339
  switch (eventType) {
211
340
  case EventType.Connect:
212
341
  if (!((_a = this.eventHandler) === null || _a === void 0 ? void 0 : _a.handleConnect)) {
342
+ if (isMqtt)
343
+ response.statusCode = 204;
213
344
  response.end();
214
345
  return true;
215
346
  }
@@ -238,7 +369,9 @@ class CloudEventsDispatcher {
238
369
  }
239
370
  switch (eventType) {
240
371
  case EventType.Connect: {
241
- const connectRequest = await readSystemEventRequest(request, origin);
372
+ const connectRequest = isMqtt
373
+ ? await readSystemEventRequest(request, origin)
374
+ : await readSystemEventRequest(request, origin);
242
375
  // service passes out query property, assign it to queries
243
376
  connectRequest.queries = connectRequest.query;
244
377
  logger_js_1.logger.verbose(connectRequest);
@@ -256,7 +389,9 @@ class CloudEventsDispatcher {
256
389
  case EventType.Disconnected: {
257
390
  // for unblocking events, we responds to the service as early as possible
258
391
  response.end();
259
- const disconnectedRequest = await readSystemEventRequest(request, origin);
392
+ const disconnectedRequest = isMqtt
393
+ ? await readSystemEventRequest(request, origin)
394
+ : await readSystemEventRequest(request, origin);
260
395
  logger_js_1.logger.verbose(disconnectedRequest);
261
396
  this.eventHandler.onDisconnected(disconnectedRequest);
262
397
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"cloudEventsDispatcher.js","sourceRoot":"","sources":["../../src/cloudEventsDispatcher.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;;AAElC,0DAAoC;AAEpC,uCAA+B;AAC/B,2CAAqC;AAcrC,IAAK,SAKJ;AALD,WAAK,SAAS;IACZ,+CAAO,CAAA;IACP,mDAAS,CAAA;IACT,yDAAY,CAAA;IACZ,mDAAS,CAAA;AACX,CAAC,EALI,SAAS,KAAT,SAAS,QAKb;AAED,SAAS,yBAAyB,CAChC,cAA8B,EAC9B,QAAwB;IAExB,MAAM,MAAM,GAAwB,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC;IAClE,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,OAAO,GAAG;QACd,QAAQ,CAAC,IAAY,EAAE,KAAc;YACnC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YACrB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,GAAqB;YAC3B,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;YAC1B,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,SAAS,CAAC,oBAAoB,EAAE,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7E,CAAC;YACD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,QAAQ,CAAC,GAAG,EAAE,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;gBACtE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAqB,EAAE,MAAe;YACzC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,QAAQ,CAAC,GAAG,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,2BAA2B,CAClC,WAA6B,EAC7B,QAAwB;IAExB,MAAM,MAAM,GAAwB,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;IAC/D,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,OAAO,GAAG;QACd,QAAQ,CAAC,IAAY,EAAE,KAAc;YACnC,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;QACD,OAAO,CAAC,IAA2B,EAAE,QAAqC;YACxE,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;YAC1B,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,SAAS,CAAC,oBAAoB,EAAE,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7E,CAAC;YAED,QAAQ,QAAQ,EAAE,CAAC;gBACjB,KAAK,MAAM;oBACT,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;oBACtE,MAAM;gBACR,KAAK,MAAM;oBACT,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,2BAA2B,CAAC,CAAC;oBAChE,MAAM;gBACR;oBACE,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;oBAC/D,MAAM;YACV,CAAC;YACD,QAAQ,CAAC,GAAG,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,IAAqB,EAAE,MAAe;YACzC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,QAAQ,CAAC,GAAG,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,OAAwB,EAAE,MAAc;IAC1D,MAAM,OAAO,GAAG;QACd,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC;QACvD,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC;QACjD,GAAG,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAE;QAC5C,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,iBAAiB,CAAE;QAC9D,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAE;QACxD,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;KACvF,CAAC;IAEF,mBAAmB;IACnB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAoB;IAChD,qEAAqE;IACrE,MAAM,MAAM,GAAG,kBAAkB,CAAC;IAClC,MAAM,OAAO,GAAG,6BAA6B,CAAC;IAC9C,MAAM,SAAS,GAAG,+BAA+B,CAAC;IAClD,MAAM,WAAW,GAAG,kCAAkC,CAAC;IACvD,MAAM,UAAU,GAAG,uBAAuB,CAAC;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,UAAU,CAAC,MAAM,CAAC,CAAA,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC,SAAS,CAAC;IAC7B,CAAC;IACD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,SAAS,CAAC,OAAO,CAAC;QAC3B,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC,SAAS,CAAC;QAC7B,KAAK,WAAW;YACd,OAAO,SAAS,CAAC,YAAY,CAAC;QAChC;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAoB;IAC9C,OAAO,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,gBAAgB,CAAC,KAAK,SAAS,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAAwB,EACxB,MAAc;IAEd,MAAM,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACvE,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE3D,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,0BAA0B;YAC7B,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;gBACpC,IAAI,EAAE,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC;gBAC1C,QAAQ,EAAE,QAAQ;aACnB,CAAC;QACJ,KAAK,kBAAkB;YACrB,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;gBACpC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACnE,QAAQ,EAAE,MAAM;aACjB,CAAC;QACJ,KAAK,YAAY;YACf,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;gBACpC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;gBACvD,QAAQ,EAAE,MAAM;aACjB,CAAC;QACJ;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,OAAwB,EACxB,MAAc;IAEd,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC5C,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAa,qBAAqB;IAGhC,YACU,GAAW,EACX,YAA2C;QAD3C,QAAG,GAAH,GAAG,CAAQ;QACX,iBAAY,GAAZ,YAAY,CAA+B;QAJpC,cAAS,GAAY,IAAI,CAAC;QAC1B,oBAAe,GAAkB,EAAE,CAAC;QAKnD,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,gBAAgB,MAAK,SAAS,EAAE,CAAC;YACjD,IAAI,CAAC,eAAe,GAAG,YAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CACpE,IAAI,cAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CACrC,CAAC;YACF,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,eAAe,CAAC,GAAoB,EAAE,GAAmB;QAC9D,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;QAElE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,kBAAM,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;YAC3D,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,0BAA0B;YAC1B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAChE,CAAC;QAED,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,OAAwB,EAAE,QAAwB;;QAC3E,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,gDAAgD;QAChD,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;QACtE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,uBAAuB;QACvB,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,EAAE,MAAK,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,mDAAmD;QACnD,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,SAAS,CAAC,OAAO;gBACpB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,aAAa,CAAA,EAAE,CAAC;oBACtC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC,SAAS;gBACtB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,WAAW,CAAA,EAAE,CAAC;oBACpC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC,YAAY;gBACzB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,cAAc,CAAA,EAAE,CAAC;oBACvC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC,SAAS;gBACtB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,eAAe,CAAA,EAAE,CAAC;oBACxC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR;gBACE,kBAAM,CAAC,OAAO,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;gBACjD,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;gBACvB,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAiB,OAAO,EAAE,MAAM,CAAC,CAAC;gBACrF,0DAA0D;gBAC1D,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC;gBAC9C,kBAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAE/B,IAAI,CAAC,YAAY,CAAC,aAAc,CAC9B,cAAc,EACd,yBAAyB,CAAC,cAAc,EAAE,QAAQ,CAAC,CACpD,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;gBACzB,yEAAyE;gBACzE,QAAQ,CAAC,GAAG,EAAE,CAAC;gBACf,MAAM,gBAAgB,GAAG,MAAM,sBAAsB,CAAmB,OAAO,EAAE,MAAM,CAAC,CAAC;gBACzF,kBAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBACjC,IAAI,CAAC,YAAY,CAAC,WAAY,CAAC,gBAAgB,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,KAAK,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;gBAC5B,yEAAyE;gBACzE,QAAQ,CAAC,GAAG,EAAE,CAAC;gBACf,MAAM,mBAAmB,GAAG,MAAM,sBAAsB,CACtD,OAAO,EACP,MAAM,CACP,CAAC;gBACF,kBAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;gBACpC,IAAI,CAAC,YAAY,CAAC,cAAe,CAAC,mBAAmB,CAAC,CAAC;gBACvD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;gBACzB,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAChE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,kBAAM,CAAC,OAAO,CACZ,4BAA4B,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAC3E,CAAC;oBACF,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,kBAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAC5B,IAAI,CAAC,YAAY,CAAC,eAAgB,CAChC,WAAW,EACX,2BAA2B,CAAC,WAAW,EAAE,QAAQ,CAAC,CACnD,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD;gBACE,kBAAM,CAAC,OAAO,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;gBACjD,OAAO,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;CACF;AA/ID,sDA+IC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport * as utils from \"./utils.js\";\nimport { IncomingMessage, ServerResponse } from \"node:http\";\nimport { URL } from \"node:url\";\nimport { logger } from \"./logger.js\";\n\nimport type {\n ConnectRequest,\n ConnectResponse,\n ConnectedRequest,\n ConnectionContext,\n ConnectResponseHandler,\n DisconnectedRequest,\n UserEventRequest,\n UserEventResponseHandler,\n WebPubSubEventHandlerOptions,\n} from \"./cloudEventsProtocols.js\";\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(request: IncomingMessage, origin: string): ConnectionContext {\n const context = {\n signature: utils.getHttpHeader(request, \"ce-signature\"),\n userId: utils.getHttpHeader(request, \"ce-userid\"),\n hub: utils.getHttpHeader(request, \"ce-hub\")!,\n connectionId: utils.getHttpHeader(request, \"ce-connectionid\")!,\n eventName: utils.getHttpHeader(request, \"ce-eventname\")!,\n origin: origin,\n states: utils.fromBase64JsonString(utils.getHttpHeader(request, \"ce-connectionstate\")),\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\nasync function readUserEventRequest(\n request: IncomingMessage,\n origin: string,\n): Promise<UserEventRequest | undefined> {\n const contentTypeheader = utils.getHttpHeader(request, \"content-type\");\n if (contentTypeheader === undefined) {\n return undefined;\n }\n\n const contentType = contentTypeheader.split(\";\")[0].trim();\n\n switch (contentType) {\n case \"application/octet-stream\":\n return {\n context: getContext(request, origin),\n data: await utils.readRequestBody(request),\n dataType: \"binary\",\n };\n case \"application/json\":\n return {\n context: getContext(request, origin),\n data: JSON.parse((await utils.readRequestBody(request)).toString()),\n dataType: \"json\",\n };\n case \"text/plain\":\n return {\n context: getContext(request, origin),\n data: (await utils.readRequestBody(request)).toString(),\n dataType: \"text\",\n };\n default:\n return undefined;\n }\n}\n\nasync function readSystemEventRequest<T extends { context: ConnectionContext }>(\n request: IncomingMessage,\n origin: string,\n): Promise<T> {\n const body = (await utils.readRequestBody(request)).toString();\n const parsedRequest = JSON.parse(body) as T;\n parsedRequest.context = getContext(request, origin);\n return parsedRequest;\n}\n\n/**\n * @internal\n */\nexport class CloudEventsDispatcher {\n private readonly _allowAll: boolean = true;\n private readonly _allowedOrigins: Array<string> = [];\n constructor(\n private hub: string,\n private eventHandler?: WebPubSubEventHandlerOptions,\n ) {\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\");\n\n if (origin === undefined) {\n logger.warning(\"Expecting webhook-request-origin header.\");\n res.statusCode = 400;\n } else if (this._allowAll) {\n res.setHeader(\"WebHook-Allowed-Origin\", \"*\");\n } else {\n // service to do the check\n res.setHeader(\"WebHook-Allowed-Origin\", this._allowedOrigins);\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?.toUpperCase() !== this.hub.toUpperCase()) {\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 switch (eventType) {\n case EventType.Connect: {\n const connectRequest = await readSystemEventRequest<ConnectRequest>(request, origin);\n // service passes out query property, assign it to queries\n connectRequest.queries = connectRequest.query;\n logger.verbose(connectRequest);\n\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 = await readSystemEventRequest<ConnectedRequest>(request, origin);\n logger.verbose(connectedRequest);\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 = await readSystemEventRequest<DisconnectedRequest>(\n request,\n origin,\n );\n logger.verbose(disconnectedRequest);\n this.eventHandler.onDisconnected!(disconnectedRequest);\n return true;\n }\n case EventType.UserEvent: {\n const userRequest = await readUserEventRequest(request, origin);\n if (userRequest === undefined) {\n logger.warning(\n `Unsupported content type ${utils.getHttpHeader(request, \"content-type\")}`,\n );\n return false;\n }\n logger.verbose(userRequest);\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"]}
1
+ {"version":3,"file":"cloudEventsDispatcher.js","sourceRoot":"","sources":["../../src/cloudEventsDispatcher.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;;AAElC,0DAAoC;AAEpC,uCAA+B;AAC/B,2CAAqC;AAkBrC,qGAA+F;AAC/F,qGAA+F;AAE/F,IAAK,SAKJ;AALD,WAAK,SAAS;IACZ,+CAAO,CAAA;IACP,mDAAS,CAAA;IACT,yDAAY,CAAA;IACZ,mDAAS,CAAA;AACX,CAAC,EALI,SAAS,KAAT,SAAS,QAKb;AAED,SAAS,yBAAyB,CAChC,cAA8B,EAC9B,QAAwB;IAExB,MAAM,MAAM,GAAwB,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC;IAClE,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,OAAO,GAAG;QACd,QAAQ,CAAC,IAAY,EAAE,KAAc;YACnC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YACrB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,GAAqB;YAC3B,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,SAAS,CAAC,oBAAoB,EAAE,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7E,CAAC;YACD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;gBAC1B,QAAQ,CAAC,GAAG,EAAE,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;gBAC1B,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;gBACtE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAqB,EAAE,MAAe;YACzC,0BAA0B,CAAC,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACrE,CAAC;QACD,QAAQ,CAAC,GAAoD;YAC3D,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;gBAClB,QAAQ,CAAC,UAAU,GAAG,gCAAgC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;gBACtE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,0BAA0B,CAAC,cAAc,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;KACF,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,2BAA2B,CAClC,WAA6B,EAC7B,QAAwB;IAExB,MAAM,MAAM,GAAwB,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;IAC/D,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,OAAO,GAAG;QACd,QAAQ,CAAC,IAAY,EAAE,KAAc;YACnC,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;QACD,OAAO,CAAC,IAA2B,EAAE,QAAqC;YACxE,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;YAC1B,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,SAAS,CAAC,oBAAoB,EAAE,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7E,CAAC;YAED,QAAQ,QAAQ,EAAE,CAAC;gBACjB,KAAK,MAAM;oBACT,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;oBACtE,MAAM;gBACR,KAAK,MAAM;oBACT,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,2BAA2B,CAAC,CAAC;oBAChE,MAAM;gBACR;oBACE,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;oBAC/D,MAAM;YACV,CAAC;YACD,QAAQ,CAAC,GAAG,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,IAAqB,EAAE,MAAe;YACzC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,QAAQ,CAAC,GAAG,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,OAAwB,EAAE,MAAc;IAC1D,MAAM,WAAW,GAAsB;QACrC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAE;QACxD,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC;QACjD,GAAG,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAE;QAC5C,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,iBAAiB,CAAE;QAC9D,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAE;QACxD,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;QACtF,cAAc,EAAE,SAAS;KAC1B,CAAC;IAEF,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,cAAc,GAAoC;YACtD,oBAAoB,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,yBAAyB,CAAE;YAC9E,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC;SACxD,CAAC;QACF,uCACK,WAAW,KACd,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,cAAc,IACpB;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAoB;IAChD,qEAAqE;IACrE,MAAM,MAAM,GAAG,kBAAkB,CAAC;IAClC,MAAM,OAAO,GAAG,6BAA6B,CAAC;IAC9C,MAAM,SAAS,GAAG,+BAA+B,CAAC;IAClD,MAAM,WAAW,GAAG,kCAAkC,CAAC;IACvD,MAAM,UAAU,GAAG,uBAAuB,CAAC;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,UAAU,CAAC,MAAM,CAAC,CAAA,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC,SAAS,CAAC;IAC7B,CAAC;IACD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,SAAS,CAAC,OAAO,CAAC;QAC3B,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC,SAAS,CAAC;QAC7B,KAAK,WAAW;YACd,OAAO,SAAS,CAAC,YAAY,CAAC;QAChC;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,gCAAgC,CACvC,eAAsE;IAEtE,IAAI,eAAe,GAAG,IAAI,EAAE,CAAC;QAC3B,QAAQ,eAAe,EAAE,CAAC;YACxB,KAAK,wDAAyB,CAAC,2BAA2B,CAAC;YAC3D,KAAK,wDAAyB,CAAC,kBAAkB;gBAC/C,OAAO,GAAG,CAAC,CAAC,aAAa;YAC3B,KAAK,wDAAyB,CAAC,iBAAiB;gBAC9C,OAAO,GAAG,CAAC,CAAC,qBAAqB;YACnC,KAAK,wDAAyB,CAAC,qBAAqB,CAAC;YACrD,KAAK,wDAAyB,CAAC,aAAa;gBAC1C,OAAO,GAAG,CAAC,CAAC,eAAe;YAC7B;gBACE,kBAAM,CAAC,OAAO,CAAC,qCAAqC,eAAe,GAAG,CAAC,CAAC;gBACxE,OAAO,GAAG,CAAC,CAAC,sBAAsB;QACtC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,QAAQ,eAAe,EAAE,CAAC;YACxB,KAAK,wDAAyB,CAAC,aAAa,CAAC;YAC7C,KAAK,wDAAyB,CAAC,qBAAqB;gBAClD,OAAO,GAAG,CAAC,CAAC,eAAe;YAC7B,KAAK,wDAAyB,CAAC,wBAAwB,CAAC;YACxD,KAAK,wDAAyB,CAAC,eAAe,CAAC;YAC/C,KAAK,wDAAyB,CAAC,0BAA0B,CAAC;YAC1D,KAAK,wDAAyB,CAAC,uBAAuB,CAAC;YACvD,KAAK,wDAAyB,CAAC,gBAAgB,CAAC;YAChD,KAAK,wDAAyB,CAAC,oBAAoB,CAAC;YACpD,KAAK,wDAAyB,CAAC,2BAA2B,CAAC;YAC3D,KAAK,wDAAyB,CAAC,cAAc,CAAC;YAC9C,KAAK,wDAAyB,CAAC,kBAAkB,CAAC;YAClD,KAAK,wDAAyB,CAAC,eAAe;gBAC5C,OAAO,GAAG,CAAC,CAAC,aAAa;YAC3B,KAAK,wDAAyB,CAAC,aAAa,CAAC;YAC7C,KAAK,wDAAyB,CAAC,sBAAsB;gBACnD,OAAO,GAAG,CAAC,CAAC,kBAAkB;YAChC,KAAK,wDAAyB,CAAC,MAAM;gBACnC,OAAO,GAAG,CAAC,CAAC,YAAY;YAC1B,KAAK,wDAAyB,CAAC,gBAAgB,CAAC;YAChD,KAAK,wDAAyB,CAAC,WAAW,CAAC;YAC3C,KAAK,wDAAyB,CAAC,iBAAiB,CAAC;YACjD,KAAK,wDAAyB,CAAC,UAAU,CAAC;YAC1C,KAAK,wDAAyB,CAAC,gBAAgB;gBAC7C,OAAO,GAAG,CAAC,CAAC,sBAAsB;YACpC;gBACE,kBAAM,CAAC,OAAO,CAAC,qCAAqC,eAAe,GAAG,CAAC,CAAC;gBACxE,OAAO,GAAG,CAAC,CAAC,sBAAsB;QACtC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gCAAgC,CACvC,UAA2B,EAC3B,eAAuB;IAEvB,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QAC1B,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,GAAG;gBACN,OAAO,wDAAyB,CAAC,qBAAqB,CAAC;YACzD,KAAK,GAAG;gBACN,OAAO,wDAAyB,CAAC,aAAa,CAAC;YACjD,KAAK,GAAG;gBACN,OAAO,wDAAyB,CAAC,iBAAiB,CAAC;YACrD;gBACE,kBAAM,CAAC,OAAO,CAAC,iCAAiC,UAAU,GAAG,CAAC,CAAC;gBAC/D,OAAO,wDAAyB,CAAC,iBAAiB,CAAC;QACvD,CAAC;IACH,CAAC;SAAM,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QACjC,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,GAAG;gBACN,OAAO,wDAAyB,CAAC,qBAAqB,CAAC;YACzD,KAAK,GAAG;gBACN,OAAO,wDAAyB,CAAC,aAAa,CAAC;YACjD,KAAK,GAAG;gBACN,OAAO,wDAAyB,CAAC,gBAAgB,CAAC;YACpD;gBACE,kBAAM,CAAC,OAAO,CAAC,iCAAiC,UAAU,GAAG,CAAC,CAAC;gBAC/D,OAAO,wDAAyB,CAAC,gBAAgB,CAAC;QACtD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,kBAAM,CAAC,OAAO,CAAC,kCAAkC,eAAe,GAAG,CAAC,CAAC;QACrE,OAAO,wDAAyB,CAAC,2BAA2B,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CACjC,cAA8B,EAC9B,QAAwB,EACxB,IAAqB,EACrB,MAAe;IAEf,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,cAAc,KAAK,MAAM,CAAC;IACnE,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,eAAe,GAAI,cAAqC,CAAC,IAAI,CAAC,eAAe,CAAC;QACpF,MAAM,iBAAiB,GAA6B;YAClD,IAAI,EAAE;gBACJ,IAAI,EAAE,gCAAgC,CAAC,IAAI,EAAE,eAAe,CAAC;gBAC7D,MAAM,EAAE,MAAM;aACf;SACF,CAAC;QACF,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;QAC3B,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;QACtE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;QAC3B,QAAQ,CAAC,GAAG,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAoB;IAC9C,OAAO,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,gBAAgB,CAAC,KAAK,SAAS,CAAC;AAClE,CAAC;AAED,SAAS,aAAa,CAAC,GAAoB;IACzC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC/D,MAAM,oBAAoB,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;IACjF,OAAO,CACL,WAAW,KAAK,SAAS;QACzB,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1C,oBAAoB,KAAK,SAAS,CACnC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAAwB,EACxB,MAAc;IAEd,MAAM,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACvE,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE3D,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,0BAA0B;YAC7B,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;gBACpC,IAAI,EAAE,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC;gBAC1C,QAAQ,EAAE,QAAQ;aACnB,CAAC;QACJ,KAAK,kBAAkB;YACrB,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;gBACpC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACnE,QAAQ,EAAE,MAAM;aACjB,CAAC;QACJ,KAAK,YAAY;YACf,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;gBACpC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;gBACvD,QAAQ,EAAE,MAAM;aACjB,CAAC;QACJ;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,OAAwB,EACxB,MAAc;IAEd,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC5C,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAa,qBAAqB;IAGhC,YACU,GAAW,EACX,YAA2C;QAD3C,QAAG,GAAH,GAAG,CAAQ;QACX,iBAAY,GAAZ,YAAY,CAA+B;QAJpC,cAAS,GAAY,IAAI,CAAC;QAC1B,oBAAe,GAAkB,EAAE,CAAC;QAKnD,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,gBAAgB,MAAK,SAAS,EAAE,CAAC;YACjD,IAAI,CAAC,eAAe,GAAG,YAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CACpE,IAAI,cAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CACrC,CAAC;YACF,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,eAAe,CAAC,GAAoB,EAAE,GAAmB;QAC9D,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;QAElE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,kBAAM,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;YAC3D,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,0BAA0B;YAC1B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAChE,CAAC;QAED,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,OAAwB,EAAE,QAAwB;;QAC3E,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,gDAAgD;QAChD,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;QACtE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,uBAAuB;QACvB,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,EAAE,MAAK,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,mDAAmD;QACnD,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,SAAS,CAAC,OAAO;gBACpB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,aAAa,CAAA,EAAE,CAAC;oBACtC,IAAI,MAAM;wBAAE,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;oBACtC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC,SAAS;gBACtB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,WAAW,CAAA,EAAE,CAAC;oBACpC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC,YAAY;gBACzB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,cAAc,CAAA,EAAE,CAAC;oBACvC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC,SAAS;gBACtB,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,YAAY,0CAAE,eAAe,CAAA,EAAE,CAAC;oBACxC,QAAQ,CAAC,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM;YACR;gBACE,kBAAM,CAAC,OAAO,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;gBACjD,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;gBACvB,MAAM,cAAc,GAAG,MAAM;oBAC3B,CAAC,CAAC,MAAM,sBAAsB,CAAqB,OAAO,EAAE,MAAM,CAAC;oBACnE,CAAC,CAAC,MAAM,sBAAsB,CAAiB,OAAO,EAAE,MAAM,CAAC,CAAC;gBAClE,0DAA0D;gBAC1D,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC;gBAC9C,kBAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAC/B,IAAI,CAAC,YAAY,CAAC,aAAc,CAC9B,cAAc,EACd,yBAAyB,CAAC,cAAc,EAAE,QAAQ,CAAC,CACpD,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;gBACzB,yEAAyE;gBACzE,QAAQ,CAAC,GAAG,EAAE,CAAC;gBACf,MAAM,gBAAgB,GAAG,MAAM,sBAAsB,CAAmB,OAAO,EAAE,MAAM,CAAC,CAAC;gBACzF,kBAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBACjC,IAAI,CAAC,YAAY,CAAC,WAAY,CAAC,gBAAgB,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,KAAK,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;gBAC5B,yEAAyE;gBACzE,QAAQ,CAAC,GAAG,EAAE,CAAC;gBACf,MAAM,mBAAmB,GAAG,MAAM;oBAChC,CAAC,CAAC,MAAM,sBAAsB,CAA0B,OAAO,EAAE,MAAM,CAAC;oBACxE,CAAC,CAAC,MAAM,sBAAsB,CAAsB,OAAO,EAAE,MAAM,CAAC,CAAC;gBACvE,kBAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;gBACpC,IAAI,CAAC,YAAY,CAAC,cAAe,CAAC,mBAAmB,CAAC,CAAC;gBACvD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;gBACzB,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAChE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,kBAAM,CAAC,OAAO,CACZ,4BAA4B,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAC3E,CAAC;oBACF,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,kBAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAC5B,IAAI,CAAC,YAAY,CAAC,eAAgB,CAChC,WAAW,EACX,2BAA2B,CAAC,WAAW,EAAE,QAAQ,CAAC,CACnD,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD;gBACE,kBAAM,CAAC,OAAO,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;gBACjD,OAAO,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;CACF;AAjJD,sDAiJC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport * as utils from \"./utils.js\";\nimport { IncomingMessage, ServerResponse } from \"node:http\";\nimport { URL } from \"node:url\";\nimport { logger } from \"./logger.js\";\n\nimport type {\n ConnectRequest,\n ConnectResponse,\n ConnectedRequest,\n ConnectionContext,\n ConnectResponseHandler,\n DisconnectedRequest,\n UserEventRequest,\n UserEventResponseHandler,\n WebPubSubEventHandlerOptions,\n MqttConnectRequest,\n MqttConnectErrorResponse,\n MqttConnectionContextProperties,\n ConnectErrorResponse,\n MqttDisconnectedRequest,\n} from \"./cloudEventsProtocols.js\";\nimport { MqttV311ConnectReturnCode } from \"./enum/MqttErrorCodes/mqttV311ConnectReturnCode.js\";\nimport { MqttV500ConnectReasonCode } from \"./enum/MqttErrorCodes/mqttV500ConnectReasonCode.js\";\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 if (modified) {\n response.setHeader(\"ce-connectionState\", utils.toBase64JsonString(states));\n }\n if (res === undefined) {\n response.statusCode = 204;\n response.end();\n } else {\n response.statusCode = 200;\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 handleConnectErrorResponse(connectRequest, response, code, detail);\n },\n failWith(res: ConnectErrorResponse | MqttConnectErrorResponse) {\n if (\"mqtt\" in res) {\n response.statusCode = getStatusCodeFromMqttConnectCode(res.mqtt.code);\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n response.end(JSON.stringify(res));\n } else {\n handleConnectErrorResponse(connectRequest, response, res.code, res.detail);\n }\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(request: IncomingMessage, origin: string): ConnectionContext {\n const baseContext: ConnectionContext = {\n signature: utils.getHttpHeader(request, \"ce-signature\")!,\n userId: utils.getHttpHeader(request, \"ce-userid\"),\n hub: utils.getHttpHeader(request, \"ce-hub\")!,\n connectionId: utils.getHttpHeader(request, \"ce-connectionid\")!,\n eventName: utils.getHttpHeader(request, \"ce-eventname\")!,\n origin: origin,\n states: utils.fromBase64JsonString(utils.getHttpHeader(request, \"ce-connectionstate\")),\n clientProtocol: \"default\",\n };\n\n if (isMqttRequest(request)) {\n const mqttProperties: MqttConnectionContextProperties = {\n physicalConnectionId: utils.getHttpHeader(request, \"ce-physicalConnectionId\")!,\n sessionId: utils.getHttpHeader(request, \"ce-sessionId\"),\n };\n return {\n ...baseContext,\n clientProtocol: \"mqtt\",\n mqtt: mqttProperties,\n };\n } else {\n return baseContext;\n }\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 getStatusCodeFromMqttConnectCode(\n mqttConnectCode: MqttV311ConnectReturnCode | MqttV500ConnectReasonCode,\n): number {\n if (mqttConnectCode < 0x80) {\n switch (mqttConnectCode) {\n case MqttV311ConnectReturnCode.UnacceptableProtocolVersion:\n case MqttV311ConnectReturnCode.IdentifierRejected:\n return 400; // BadRequest\n case MqttV311ConnectReturnCode.ServerUnavailable:\n return 503; // ServiceUnavailable\n case MqttV311ConnectReturnCode.BadUsernameOrPassword:\n case MqttV311ConnectReturnCode.NotAuthorized:\n return 401; // Unauthorized\n default:\n logger.warning(`Invalid MQTT connect return code: ${mqttConnectCode}.`);\n return 500; // InternalServerError\n }\n } else {\n switch (mqttConnectCode) {\n case MqttV500ConnectReasonCode.NotAuthorized:\n case MqttV500ConnectReasonCode.BadUserNameOrPassword:\n return 401; // Unauthorized\n case MqttV500ConnectReasonCode.ClientIdentifierNotValid:\n case MqttV500ConnectReasonCode.MalformedPacket:\n case MqttV500ConnectReasonCode.UnsupportedProtocolVersion:\n case MqttV500ConnectReasonCode.BadAuthenticationMethod:\n case MqttV500ConnectReasonCode.TopicNameInvalid:\n case MqttV500ConnectReasonCode.PayloadFormatInvalid:\n case MqttV500ConnectReasonCode.ImplementationSpecificError:\n case MqttV500ConnectReasonCode.PacketTooLarge:\n case MqttV500ConnectReasonCode.RetainNotSupported:\n case MqttV500ConnectReasonCode.QosNotSupported:\n return 400; // BadRequest\n case MqttV500ConnectReasonCode.QuotaExceeded:\n case MqttV500ConnectReasonCode.ConnectionRateExceeded:\n return 429; // TooManyRequests\n case MqttV500ConnectReasonCode.Banned:\n return 403; // Forbidden\n case MqttV500ConnectReasonCode.UseAnotherServer:\n case MqttV500ConnectReasonCode.ServerMoved:\n case MqttV500ConnectReasonCode.ServerUnavailable:\n case MqttV500ConnectReasonCode.ServerBusy:\n case MqttV500ConnectReasonCode.UnspecifiedError:\n return 500; // InternalServerError\n default:\n logger.warning(`Invalid MQTT connect return code: ${mqttConnectCode}.`);\n return 500; // InternalServerError\n }\n }\n}\n\nfunction getMqttConnectCodeFromStatusCode(\n statusCode: 400 | 401 | 500,\n protocolVersion: number,\n): MqttV311ConnectReturnCode | MqttV500ConnectReasonCode {\n if (protocolVersion === 4) {\n switch (statusCode) {\n case 400:\n return MqttV311ConnectReturnCode.BadUsernameOrPassword;\n case 401:\n return MqttV311ConnectReturnCode.NotAuthorized;\n case 500:\n return MqttV311ConnectReturnCode.ServerUnavailable;\n default:\n logger.warning(`Unsupported HTTP Status Code: ${statusCode}.`);\n return MqttV311ConnectReturnCode.ServerUnavailable;\n }\n } else if (protocolVersion === 5) {\n switch (statusCode) {\n case 400:\n return MqttV500ConnectReasonCode.BadUserNameOrPassword;\n case 401:\n return MqttV500ConnectReasonCode.NotAuthorized;\n case 500:\n return MqttV500ConnectReasonCode.UnspecifiedError;\n default:\n logger.warning(`Unsupported HTTP Status Code: ${statusCode}.`);\n return MqttV500ConnectReasonCode.UnspecifiedError;\n }\n } else {\n logger.warning(`Invalid MQTT protocol version: ${protocolVersion}.`);\n return MqttV311ConnectReturnCode.UnacceptableProtocolVersion;\n }\n}\n\nfunction handleConnectErrorResponse(\n connectRequest: ConnectRequest,\n response: ServerResponse,\n code: 400 | 401 | 500,\n detail?: string,\n): void {\n const isMqttReq = connectRequest.context.clientProtocol === \"mqtt\";\n if (isMqttReq) {\n const protocolVersion = (connectRequest as MqttConnectRequest).mqtt.protocolVersion;\n const mqttErrorResponse: MqttConnectErrorResponse = {\n mqtt: {\n code: getMqttConnectCodeFromStatusCode(code, protocolVersion),\n reason: detail,\n },\n };\n response.statusCode = code;\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n response.end(JSON.stringify(mqttErrorResponse));\n } else {\n response.statusCode = code;\n response.end(detail ?? \"\");\n }\n}\n\nfunction isWebPubSubRequest(req: IncomingMessage): boolean {\n return utils.getHttpHeader(req, \"ce-awpsversion\") !== undefined;\n}\n\nfunction isMqttRequest(req: IncomingMessage): boolean {\n const subprotocol = utils.getHttpHeader(req, \"ce-subprotocol\");\n const physicalConnectionId = utils.getHttpHeader(req, \"ce-physicalConnectionId\");\n return (\n subprotocol !== undefined &&\n subprotocol.toLowerCase().includes(\"mqtt\") &&\n physicalConnectionId !== undefined\n );\n}\n\nasync function readUserEventRequest(\n request: IncomingMessage,\n origin: string,\n): Promise<UserEventRequest | undefined> {\n const contentTypeheader = utils.getHttpHeader(request, \"content-type\");\n if (contentTypeheader === undefined) {\n return undefined;\n }\n\n const contentType = contentTypeheader.split(\";\")[0].trim();\n\n switch (contentType) {\n case \"application/octet-stream\":\n return {\n context: getContext(request, origin),\n data: await utils.readRequestBody(request),\n dataType: \"binary\",\n };\n case \"application/json\":\n return {\n context: getContext(request, origin),\n data: JSON.parse((await utils.readRequestBody(request)).toString()),\n dataType: \"json\",\n };\n case \"text/plain\":\n return {\n context: getContext(request, origin),\n data: (await utils.readRequestBody(request)).toString(),\n dataType: \"text\",\n };\n default:\n return undefined;\n }\n}\n\nasync function readSystemEventRequest<T extends { context: ConnectionContext }>(\n request: IncomingMessage,\n origin: string,\n): Promise<T> {\n const body = (await utils.readRequestBody(request)).toString();\n const parsedRequest = JSON.parse(body) as T;\n parsedRequest.context = getContext(request, origin);\n return parsedRequest;\n}\n\n/**\n * @internal\n */\nexport class CloudEventsDispatcher {\n private readonly _allowAll: boolean = true;\n private readonly _allowedOrigins: Array<string> = [];\n constructor(\n private hub: string,\n private eventHandler?: WebPubSubEventHandlerOptions,\n ) {\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\");\n\n if (origin === undefined) {\n logger.warning(\"Expecting webhook-request-origin header.\");\n res.statusCode = 400;\n } else if (this._allowAll) {\n res.setHeader(\"WebHook-Allowed-Origin\", \"*\");\n } else {\n // service to do the check\n res.setHeader(\"WebHook-Allowed-Origin\", this._allowedOrigins);\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?.toUpperCase() !== this.hub.toUpperCase()) {\n return false;\n }\n\n const isMqtt = isMqttRequest(request);\n // No need to read body if handler is not specified\n switch (eventType) {\n case EventType.Connect:\n if (!this.eventHandler?.handleConnect) {\n if (isMqtt) response.statusCode = 204;\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 switch (eventType) {\n case EventType.Connect: {\n const connectRequest = isMqtt\n ? await readSystemEventRequest<MqttConnectRequest>(request, origin)\n : await readSystemEventRequest<ConnectRequest>(request, origin);\n // service passes out query property, assign it to queries\n connectRequest.queries = connectRequest.query;\n logger.verbose(connectRequest);\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 = await readSystemEventRequest<ConnectedRequest>(request, origin);\n logger.verbose(connectedRequest);\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 = isMqtt\n ? await readSystemEventRequest<MqttDisconnectedRequest>(request, origin)\n : await readSystemEventRequest<DisconnectedRequest>(request, origin);\n logger.verbose(disconnectedRequest);\n this.eventHandler.onDisconnected!(disconnectedRequest);\n return true;\n }\n case EventType.UserEvent: {\n const userRequest = await readUserEventRequest(request, origin);\n if (userRequest === undefined) {\n logger.warning(\n `Unsupported content type ${utils.getHttpHeader(request, \"content-type\")}`,\n );\n return false;\n }\n logger.verbose(userRequest);\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"]}