@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.
- package/README.md +53 -46
- package/dist/browser/cloudEventsDispatcher.d.ts +15 -0
- package/dist/browser/cloudEventsDispatcher.d.ts.map +1 -0
- package/dist/browser/cloudEventsDispatcher.js +411 -0
- package/dist/browser/cloudEventsDispatcher.js.map +1 -0
- package/dist/browser/cloudEventsProtocols.d.ts +411 -0
- package/dist/browser/cloudEventsProtocols.d.ts.map +1 -0
- package/dist/browser/cloudEventsProtocols.js +4 -0
- package/dist/browser/cloudEventsProtocols.js.map +1 -0
- package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts +180 -0
- package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts.map +1 -0
- package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.js +183 -0
- package/dist/browser/enum/MqttErrorCodes/mqttDisconnectReasonCode.js.map +1 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts +31 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts.map +1 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js +34 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js.map +1 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts +112 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts.map +1 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js +115 -0
- package/dist/browser/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js.map +1 -0
- package/dist/browser/index.d.ts +6 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +8 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/logger.d.ts +7 -0
- package/dist/browser/logger.d.ts.map +1 -0
- package/dist/browser/logger.js +10 -0
- package/dist/browser/logger.js.map +1 -0
- package/dist/browser/package.json +3 -0
- package/dist/browser/utils.d.ts +6 -0
- package/dist/browser/utils.d.ts.map +1 -0
- package/dist/browser/utils.js +53 -0
- package/dist/browser/utils.js.map +1 -0
- package/dist/browser/webPubSubEventHandler.d.ts +46 -0
- package/dist/browser/webPubSubEventHandler.d.ts.map +1 -0
- package/dist/browser/webPubSubEventHandler.js +73 -0
- package/dist/browser/webPubSubEventHandler.js.map +1 -0
- package/dist/commonjs/index.js +14 -880
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/webPubSubEventHandler.d.ts +7 -8
- package/dist/commonjs/webPubSubEventHandler.d.ts.map +1 -1
- package/dist/commonjs/webPubSubEventHandler.js +7 -8
- package/dist/commonjs/webPubSubEventHandler.js.map +1 -1
- package/dist/esm/webPubSubEventHandler.d.ts +7 -8
- package/dist/esm/webPubSubEventHandler.d.ts.map +1 -1
- package/dist/esm/webPubSubEventHandler.js +7 -8
- package/dist/esm/webPubSubEventHandler.js.map +1 -1
- package/dist/react-native/cloudEventsDispatcher.d.ts +15 -0
- package/dist/react-native/cloudEventsDispatcher.d.ts.map +1 -0
- package/dist/react-native/cloudEventsDispatcher.js +411 -0
- package/dist/react-native/cloudEventsDispatcher.js.map +1 -0
- package/dist/react-native/cloudEventsProtocols.d.ts +411 -0
- package/dist/react-native/cloudEventsProtocols.d.ts.map +1 -0
- package/dist/react-native/cloudEventsProtocols.js +4 -0
- package/dist/react-native/cloudEventsProtocols.js.map +1 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts +180 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.d.ts.map +1 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.js +183 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttDisconnectReasonCode.js.map +1 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts +31 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.d.ts.map +1 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js +34 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV311ConnectReturnCode.js.map +1 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts +112 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.d.ts.map +1 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js +115 -0
- package/dist/react-native/enum/MqttErrorCodes/mqttV500ConnectReasonCode.js.map +1 -0
- package/dist/react-native/index.d.ts +6 -0
- package/dist/react-native/index.d.ts.map +1 -0
- package/dist/react-native/index.js +8 -0
- package/dist/react-native/index.js.map +1 -0
- package/dist/react-native/logger.d.ts +7 -0
- package/dist/react-native/logger.d.ts.map +1 -0
- package/dist/react-native/logger.js +10 -0
- package/dist/react-native/logger.js.map +1 -0
- package/dist/react-native/package.json +3 -0
- package/dist/react-native/utils.d.ts +6 -0
- package/dist/react-native/utils.d.ts.map +1 -0
- package/dist/react-native/utils.js +53 -0
- package/dist/react-native/utils.js.map +1 -0
- package/dist/react-native/webPubSubEventHandler.d.ts +46 -0
- package/dist/react-native/webPubSubEventHandler.d.ts.map +1 -0
- package/dist/react-native/webPubSubEventHandler.js +73 -0
- package/dist/react-native/webPubSubEventHandler.js.map +1 -0
- package/package.json +33 -17
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudEventsDispatcher.js","sourceRoot":"","sources":["../../src/cloudEventsDispatcher.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport * as utils from \"./utils.js\";\nimport type { 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"]}
|