hap-nodejs 1.0.0-beta.7 → 1.0.0
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 +7 -3
- package/dist/accessories/AirConditioner_accessory.js +24 -24
- package/dist/accessories/AirConditioner_accessory.js.map +1 -1
- package/dist/accessories/AppleTVRemote_accessory.js +23 -23
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
- package/dist/accessories/Camera_accessory.js +295 -380
- package/dist/accessories/Camera_accessory.js.map +1 -1
- package/dist/accessories/Fan_accessory.js +15 -21
- package/dist/accessories/Fan_accessory.js.map +1 -1
- package/dist/accessories/GarageDoorOpener_accessory.js +12 -12
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +31 -21
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
- package/dist/accessories/Light_accessory.js +45 -48
- package/dist/accessories/Light_accessory.js.map +1 -1
- package/dist/accessories/Lock_accessory.js +11 -11
- package/dist/accessories/Lock_accessory.js.map +1 -1
- package/dist/accessories/MotionSensor_accessory.js +8 -8
- package/dist/accessories/MotionSensor_accessory.js.map +1 -1
- package/dist/accessories/Outlet_accessory.js +10 -10
- package/dist/accessories/Outlet_accessory.js.map +1 -1
- package/dist/accessories/SmartSpeaker_accessory.js +11 -11
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
- package/dist/accessories/Sprinkler_accessory.js +19 -19
- package/dist/accessories/Sprinkler_accessory.js.map +1 -1
- package/dist/accessories/TV_accessory.js +17 -17
- package/dist/accessories/TV_accessory.js.map +1 -1
- package/dist/accessories/TemperatureSensor_accessory.js +6 -6
- package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.js +3 -3
- package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.js +4 -4
- package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.js +45 -55
- package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
- package/dist/accessories/types.js +2 -2
- package/dist/accessories/types.js.map +1 -1
- package/dist/index.d.ts +0 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -31
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +4 -4
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/internal-types.js +10 -6
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +19 -74
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +775 -1155
- package/dist/lib/Accessory.js.map +1 -1
- package/dist/lib/Advertiser.d.ts +5 -6
- package/dist/lib/Advertiser.d.ts.map +1 -1
- package/dist/lib/Advertiser.js +402 -521
- package/dist/lib/Advertiser.js.map +1 -1
- package/dist/lib/Bridge.js +6 -10
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +31 -93
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +1474 -668
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +10 -22
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +224 -286
- package/dist/lib/HAPServer.js.map +1 -1
- package/dist/lib/Service.d.ts +9 -27
- package/dist/lib/Service.d.ts.map +1 -1
- package/dist/lib/Service.js +476 -314
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +0 -2
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +112 -104
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +2 -67
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +272 -292
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +0 -1
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -1
- package/dist/lib/camera/RecordingManagement.js +325 -392
- package/dist/lib/camera/RecordingManagement.js.map +1 -1
- package/dist/lib/camera/index.d.ts +0 -1
- package/dist/lib/camera/index.d.ts.map +1 -1
- package/dist/lib/camera/index.js +1 -2
- package/dist/lib/camera/index.js.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.d.ts +19 -4
- package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.js +220 -221
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +0 -6
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +192 -258
- package/dist/lib/controller/CameraController.js.map +1 -1
- package/dist/lib/controller/Controller.d.ts +1 -1
- package/dist/lib/controller/Controller.d.ts.map +1 -1
- package/dist/lib/controller/Controller.js +3 -3
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.js +38 -39
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +4 -20
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +351 -424
- package/dist/lib/controller/RemoteController.js.map +1 -1
- package/dist/lib/controller/index.js +1 -1
- package/dist/lib/datastream/DataStreamManagement.js +57 -58
- package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
- package/dist/lib/datastream/DataStreamParser.d.ts +0 -1
- package/dist/lib/datastream/DataStreamParser.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamParser.js +261 -306
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +0 -8
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +262 -275
- package/dist/lib/datastream/DataStreamServer.js.map +1 -1
- package/dist/lib/datastream/index.js +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts +50 -40
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.js +2059 -2754
- package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts +14 -8
- package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.js +834 -1053
- package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
- package/dist/lib/definitions/generate-definitions.js +383 -679
- package/dist/lib/definitions/generate-definitions.js.map +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts.map +1 -1
- package/dist/lib/definitions/generator-configuration.js +163 -35
- package/dist/lib/definitions/generator-configuration.js.map +1 -1
- package/dist/lib/definitions/index.js +1 -1
- package/dist/lib/model/AccessoryInfo.d.ts +0 -1
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +102 -137
- package/dist/lib/model/AccessoryInfo.js.map +1 -1
- package/dist/lib/model/ControllerStorage.js +86 -89
- package/dist/lib/model/ControllerStorage.js.map +1 -1
- package/dist/lib/model/HAPStorage.js +15 -16
- package/dist/lib/model/HAPStorage.js.map +1 -1
- package/dist/lib/model/IdentifierCache.js +49 -49
- package/dist/lib/model/IdentifierCache.js.map +1 -1
- package/dist/lib/tv/AccessControlManagement.d.ts +0 -1
- package/dist/lib/tv/AccessControlManagement.d.ts.map +1 -1
- package/dist/lib/tv/AccessControlManagement.js +43 -46
- package/dist/lib/tv/AccessControlManagement.js.map +1 -1
- package/dist/lib/util/checkName.d.ts +8 -0
- package/dist/lib/util/checkName.d.ts.map +1 -0
- package/dist/lib/util/checkName.js +17 -0
- package/dist/lib/util/checkName.js.map +1 -0
- package/dist/lib/util/clone.js +6 -29
- package/dist/lib/util/clone.js.map +1 -1
- package/dist/lib/util/color-utils.js +8 -12
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +5 -9
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +306 -405
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +0 -1
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +39 -41
- package/dist/lib/util/hapCrypto.js.map +1 -1
- package/dist/lib/util/hapStatusError.js +9 -12
- package/dist/lib/util/hapStatusError.js.map +1 -1
- package/dist/lib/util/net-utils.d.ts.map +1 -1
- package/dist/lib/util/net-utils.js +34 -54
- package/dist/lib/util/net-utils.js.map +1 -1
- package/dist/lib/util/once.js +4 -10
- package/dist/lib/util/once.js.map +1 -1
- package/dist/lib/util/promise-utils.d.ts +0 -1
- package/dist/lib/util/promise-utils.d.ts.map +1 -1
- package/dist/lib/util/promise-utils.js +10 -16
- package/dist/lib/util/promise-utils.js.map +1 -1
- package/dist/lib/util/request-util.js +8 -10
- package/dist/lib/util/request-util.js.map +1 -1
- package/dist/lib/util/time.d.ts +0 -1
- package/dist/lib/util/time.d.ts.map +1 -1
- package/dist/lib/util/time.js +7 -8
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +0 -28
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +83 -126
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +0 -10
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +22 -40
- package/dist/lib/util/uuid.js.map +1 -1
- package/dist/types.d.ts +0 -35
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +29 -28
- package/dist/BridgedCore.d.ts +0 -2
- package/dist/BridgedCore.d.ts.map +0 -1
- package/dist/BridgedCore.js +0 -43
- package/dist/BridgedCore.js.map +0 -1
- package/dist/Core.d.ts +0 -2
- package/dist/Core.d.ts.map +0 -1
- package/dist/Core.js +0 -52
- package/dist/Core.js.map +0 -1
- package/dist/lib/AccessoryLoader.d.ts +0 -28
- package/dist/lib/AccessoryLoader.d.ts.map +0 -1
- package/dist/lib/AccessoryLoader.js +0 -167
- package/dist/lib/AccessoryLoader.js.map +0 -1
- package/dist/lib/camera/Camera.d.ts +0 -44
- package/dist/lib/camera/Camera.d.ts.map +0 -1
- package/dist/lib/camera/Camera.js +0 -36
- package/dist/lib/camera/Camera.js.map +0 -1
package/dist/lib/HAPServer.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HAPServer = exports.HAPServerEventTypes = exports.HAPPairingHTTPCode = exports.HAPHTTPCode = exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
exports.HAPServer = exports.HAPServerEventTypes = exports.HAPPairingHTTPCode = exports.HAPHTTPCode = exports.HAPStatus = exports.TLVErrorCode = void 0;
|
|
4
|
+
exports.IsKnownHAPStatusError = IsKnownHAPStatusError;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
7
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
8
|
+
const events_1 = require("events");
|
|
9
|
+
const fast_srp_hap_1 = require("fast-srp-hap");
|
|
10
|
+
const tweetnacl_1 = tslib_1.__importDefault(require("tweetnacl"));
|
|
11
|
+
const url_1 = require("url");
|
|
12
|
+
const internal_types_1 = require("../internal-types");
|
|
13
|
+
const eventedhttp_1 = require("./util/eventedhttp");
|
|
14
|
+
const hapCrypto = tslib_1.__importStar(require("./util/hapCrypto"));
|
|
15
|
+
const once_1 = require("./util/once");
|
|
16
|
+
const tlv = tslib_1.__importStar(require("./util/tlv"));
|
|
17
|
+
const debug = (0, debug_1.default)("HAP-NodeJS:HAPServer");
|
|
17
18
|
/**
|
|
18
19
|
* TLV error codes for the `TLVValues.ERROR_CODE` field.
|
|
19
20
|
*
|
|
@@ -24,13 +25,14 @@ var TLVErrorCode;
|
|
|
24
25
|
// noinspection JSUnusedGlobalSymbols
|
|
25
26
|
TLVErrorCode[TLVErrorCode["UNKNOWN"] = 1] = "UNKNOWN";
|
|
26
27
|
TLVErrorCode[TLVErrorCode["INVALID_REQUEST"] = 2] = "INVALID_REQUEST";
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
27
29
|
TLVErrorCode[TLVErrorCode["AUTHENTICATION"] = 2] = "AUTHENTICATION";
|
|
28
30
|
TLVErrorCode[TLVErrorCode["BACKOFF"] = 3] = "BACKOFF";
|
|
29
31
|
TLVErrorCode[TLVErrorCode["MAX_PEERS"] = 4] = "MAX_PEERS";
|
|
30
32
|
TLVErrorCode[TLVErrorCode["MAX_TRIES"] = 5] = "MAX_TRIES";
|
|
31
33
|
TLVErrorCode[TLVErrorCode["UNAVAILABLE"] = 6] = "UNAVAILABLE";
|
|
32
34
|
TLVErrorCode[TLVErrorCode["BUSY"] = 7] = "BUSY"; // cannot accept pairing request at this time
|
|
33
|
-
})(TLVErrorCode
|
|
35
|
+
})(TLVErrorCode || (exports.TLVErrorCode = TLVErrorCode = {}));
|
|
34
36
|
/**
|
|
35
37
|
* @group HAP Accessory Server
|
|
36
38
|
*/
|
|
@@ -90,7 +92,7 @@ var HAPStatus;
|
|
|
90
92
|
*/
|
|
91
93
|
HAPStatus[HAPStatus["NOT_ALLOWED_IN_CURRENT_STATE"] = -70412] = "NOT_ALLOWED_IN_CURRENT_STATE";
|
|
92
94
|
// when adding new status codes, remember to update bounds in IsKnownHAPStatusError below
|
|
93
|
-
})(HAPStatus
|
|
95
|
+
})(HAPStatus || (exports.HAPStatus = HAPStatus = {}));
|
|
94
96
|
/**
|
|
95
97
|
* Determines if the given status code is a known {@link HAPStatus} error code.
|
|
96
98
|
*
|
|
@@ -103,21 +105,6 @@ function IsKnownHAPStatusError(status) {
|
|
|
103
105
|
// Upper bound (negative error code closest to zero)
|
|
104
106
|
status <= -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */);
|
|
105
107
|
}
|
|
106
|
-
exports.IsKnownHAPStatusError = IsKnownHAPStatusError;
|
|
107
|
-
// noinspection JSUnusedGlobalSymbols
|
|
108
|
-
/**
|
|
109
|
-
* @group HAP Accessory Server
|
|
110
|
-
* @deprecated please use {@link TLVErrorCode} as naming is more precise
|
|
111
|
-
*/
|
|
112
|
-
// @ts-expect-error (as we use const enums with --preserveConstEnums)
|
|
113
|
-
exports.Codes = TLVErrorCode;
|
|
114
|
-
// noinspection JSUnusedGlobalSymbols
|
|
115
|
-
/**
|
|
116
|
-
* @group HAP Accessory Server
|
|
117
|
-
* @deprecated please use {@link HAPStatus} as naming is more precise
|
|
118
|
-
*/
|
|
119
|
-
// @ts-expect-error (as we use const enums with --preserveConstEnums)
|
|
120
|
-
exports.Status = HAPStatus;
|
|
121
108
|
/**
|
|
122
109
|
* Those status codes are the one listed as appropriate for the HAP spec!
|
|
123
110
|
*
|
|
@@ -141,7 +128,7 @@ var HAPHTTPCode;
|
|
|
141
128
|
// server error
|
|
142
129
|
HAPHTTPCode[HAPHTTPCode["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
143
130
|
HAPHTTPCode[HAPHTTPCode["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
|
|
144
|
-
})(HAPHTTPCode
|
|
131
|
+
})(HAPHTTPCode || (exports.HAPHTTPCode = HAPHTTPCode = {}));
|
|
145
132
|
/**
|
|
146
133
|
* When in a request is made to the pairing endpoints, and mime type is 'application/pairing+tlv8'
|
|
147
134
|
* one should use the below status codes.
|
|
@@ -157,7 +144,7 @@ var HAPPairingHTTPCode;
|
|
|
157
144
|
HAPPairingHTTPCode[HAPPairingHTTPCode["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
|
158
145
|
HAPPairingHTTPCode[HAPPairingHTTPCode["CONNECTION_AUTHORIZATION_REQUIRED"] = 470] = "CONNECTION_AUTHORIZATION_REQUIRED";
|
|
159
146
|
HAPPairingHTTPCode[HAPPairingHTTPCode["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
160
|
-
})(HAPPairingHTTPCode
|
|
147
|
+
})(HAPPairingHTTPCode || (exports.HAPPairingHTTPCode = HAPPairingHTTPCode = {}));
|
|
161
148
|
/**
|
|
162
149
|
* @group HAP Accessory Server
|
|
163
150
|
*/
|
|
@@ -204,7 +191,7 @@ var HAPServerEventTypes;
|
|
|
204
191
|
HAPServerEventTypes["SET_CHARACTERISTICS"] = "set-characteristics";
|
|
205
192
|
HAPServerEventTypes["REQUEST_RESOURCE"] = "request-resource";
|
|
206
193
|
HAPServerEventTypes["CONNECTION_CLOSED"] = "connection-closed";
|
|
207
|
-
})(HAPServerEventTypes
|
|
194
|
+
})(HAPServerEventTypes || (exports.HAPServerEventTypes = HAPServerEventTypes = {}));
|
|
208
195
|
/**
|
|
209
196
|
* The actual HAP server that iOS devices talk to.
|
|
210
197
|
*
|
|
@@ -226,36 +213,37 @@ var HAPServerEventTypes;
|
|
|
226
213
|
*
|
|
227
214
|
* @group HAP Accessory Server
|
|
228
215
|
*/
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
216
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
217
|
+
class HAPServer extends events_1.EventEmitter {
|
|
218
|
+
accessoryInfo;
|
|
219
|
+
httpServer;
|
|
220
|
+
unsuccessfulPairAttempts = 0; // after 100 unsuccessful attempts the server won't accept any further attempts. Will currently be reset on a reboot
|
|
221
|
+
allowInsecureRequest;
|
|
222
|
+
constructor(accessoryInfo) {
|
|
223
|
+
super();
|
|
224
|
+
this.accessoryInfo = accessoryInfo;
|
|
225
|
+
this.allowInsecureRequest = false;
|
|
236
226
|
// internal server that does all the actual communication
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return _this;
|
|
227
|
+
this.httpServer = new eventedhttp_1.EventedHTTPServer();
|
|
228
|
+
this.httpServer.on("listening" /* EventedHTTPServerEvent.LISTENING */, this.onListening.bind(this));
|
|
229
|
+
this.httpServer.on("request" /* EventedHTTPServerEvent.REQUEST */, this.handleRequestOnHAPConnection.bind(this));
|
|
230
|
+
this.httpServer.on("connection-closed" /* EventedHTTPServerEvent.CONNECTION_CLOSED */, this.handleConnectionClosed.bind(this));
|
|
242
231
|
}
|
|
243
|
-
|
|
244
|
-
if (port === void 0) { port = 0; }
|
|
232
|
+
listen(port = 0, host) {
|
|
245
233
|
if (host === "::") {
|
|
246
234
|
// this will work around "EAFNOSUPPORT: address family not supported" errors
|
|
247
235
|
// on systems where IPv6 is not supported/enabled, we just use the node default then by supplying undefined
|
|
248
236
|
host = undefined;
|
|
249
237
|
}
|
|
250
238
|
this.httpServer.listen(port, host);
|
|
251
|
-
}
|
|
252
|
-
|
|
239
|
+
}
|
|
240
|
+
stop() {
|
|
253
241
|
this.httpServer.stop();
|
|
254
|
-
}
|
|
255
|
-
|
|
242
|
+
}
|
|
243
|
+
destroy() {
|
|
256
244
|
this.stop();
|
|
257
245
|
this.removeAllListeners();
|
|
258
|
-
}
|
|
246
|
+
}
|
|
259
247
|
/**
|
|
260
248
|
* Send an even notification for given characteristic and changed value to all connected clients.
|
|
261
249
|
* If `originator` is specified, the given {@link HAPConnection} will be excluded from the broadcast.
|
|
@@ -267,48 +255,47 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
267
255
|
* @param immediateDelivery - The HAP spec requires some characteristics to be delivery immediately.
|
|
268
256
|
* Namely, for the {@link Characteristic.ButtonEvent} and the {@link Characteristic.ProgrammableSwitchEvent} characteristics.
|
|
269
257
|
*/
|
|
270
|
-
|
|
258
|
+
sendEventNotifications(aid, iid, value, originator, immediateDelivery) {
|
|
271
259
|
try {
|
|
272
260
|
this.httpServer.broadcastEvent(aid, iid, value, originator, immediateDelivery);
|
|
273
261
|
}
|
|
274
262
|
catch (error) {
|
|
275
263
|
console.warn("[" + this.accessoryInfo.username + "] Error when sending event notifications: " + error.message);
|
|
276
264
|
}
|
|
277
|
-
}
|
|
278
|
-
|
|
265
|
+
}
|
|
266
|
+
onListening(port, hostname) {
|
|
279
267
|
this.emit("listening" /* HAPServerEventTypes.LISTENING */, port, hostname);
|
|
280
|
-
}
|
|
268
|
+
}
|
|
281
269
|
// Called when an HTTP request was detected.
|
|
282
|
-
|
|
283
|
-
var _this = this;
|
|
270
|
+
handleRequestOnHAPConnection(connection, request, response) {
|
|
284
271
|
debug("[%s] HAP Request: %s %s", this.accessoryInfo.username, request.method, request.url);
|
|
285
|
-
|
|
286
|
-
request.on("data",
|
|
287
|
-
request.on("end",
|
|
288
|
-
|
|
289
|
-
|
|
272
|
+
const buffers = [];
|
|
273
|
+
request.on("data", data => buffers.push(data));
|
|
274
|
+
request.on("end", () => {
|
|
275
|
+
const url = new url_1.URL(request.url, "http://hap-nodejs.local"); // parse the url (query strings etc)
|
|
276
|
+
const handler = this.getHandler(url);
|
|
290
277
|
if (!handler) {
|
|
291
|
-
debug("[%s] WARNING: Handler for %s not implemented",
|
|
278
|
+
debug("[%s] WARNING: Handler for %s not implemented", this.accessoryInfo.username, request.url);
|
|
292
279
|
response.writeHead(404 /* HAPHTTPCode.NOT_FOUND */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
293
280
|
response.end(JSON.stringify({ status: -70409 /* HAPStatus.RESOURCE_DOES_NOT_EXIST */ }));
|
|
294
281
|
}
|
|
295
282
|
else {
|
|
296
|
-
|
|
283
|
+
const data = Buffer.concat(buffers);
|
|
297
284
|
try {
|
|
298
285
|
handler(connection, url, request, data, response);
|
|
299
286
|
}
|
|
300
287
|
catch (error) {
|
|
301
|
-
debug("[%s] Error executing route handler: %s",
|
|
288
|
+
debug("[%s] Error executing route handler: %s", this.accessoryInfo.username, error.stack);
|
|
302
289
|
response.writeHead(500 /* HAPHTTPCode.INTERNAL_SERVER_ERROR */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
303
290
|
response.end(JSON.stringify({ status: -70403 /* HAPStatus.RESOURCE_BUSY */ })); // resource busy try again, does somehow fit?
|
|
304
291
|
}
|
|
305
292
|
}
|
|
306
293
|
});
|
|
307
|
-
}
|
|
308
|
-
|
|
294
|
+
}
|
|
295
|
+
handleConnectionClosed(connection) {
|
|
309
296
|
this.emit("connection-closed" /* HAPServerEventTypes.CONNECTION_CLOSED */, connection);
|
|
310
|
-
}
|
|
311
|
-
|
|
297
|
+
}
|
|
298
|
+
getHandler(url) {
|
|
312
299
|
switch (url.pathname.toLowerCase()) {
|
|
313
300
|
case "/identify":
|
|
314
301
|
return this.handleIdentifyRequest.bind(this);
|
|
@@ -329,32 +316,31 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
329
316
|
default:
|
|
330
317
|
return undefined;
|
|
331
318
|
}
|
|
332
|
-
}
|
|
319
|
+
}
|
|
333
320
|
/**
|
|
334
321
|
* UNPAIRED Accessory identification.
|
|
335
322
|
*/
|
|
336
|
-
|
|
337
|
-
var _this = this;
|
|
323
|
+
handleIdentifyRequest(connection, url, request, data, response) {
|
|
338
324
|
// POST body is empty
|
|
339
325
|
if (this.accessoryInfo.paired() && !this.allowInsecureRequest) {
|
|
340
326
|
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
341
327
|
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
342
328
|
return;
|
|
343
329
|
}
|
|
344
|
-
this.emit("identify" /* HAPServerEventTypes.IDENTIFY */, (0, once_1.once)(
|
|
330
|
+
this.emit("identify" /* HAPServerEventTypes.IDENTIFY */, (0, once_1.once)(err => {
|
|
345
331
|
if (!err) {
|
|
346
|
-
debug("[%s] Identification success",
|
|
332
|
+
debug("[%s] Identification success", this.accessoryInfo.username);
|
|
347
333
|
response.writeHead(204 /* HAPHTTPCode.NO_CONTENT */);
|
|
348
334
|
response.end();
|
|
349
335
|
}
|
|
350
336
|
else {
|
|
351
|
-
debug("[%s] Identification error: %s",
|
|
337
|
+
debug("[%s] Identification error: %s", this.accessoryInfo.username, err.message);
|
|
352
338
|
response.writeHead(500 /* HAPHTTPCode.INTERNAL_SERVER_ERROR */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
353
339
|
response.end(JSON.stringify({ status: -70403 /* HAPStatus.RESOURCE_BUSY */ }));
|
|
354
340
|
}
|
|
355
341
|
}));
|
|
356
|
-
}
|
|
357
|
-
|
|
342
|
+
}
|
|
343
|
+
handlePairSetup(connection, url, request, data, response) {
|
|
358
344
|
// Can only be directly paired with one iOS device
|
|
359
345
|
if (!this.allowInsecureRequest && this.accessoryInfo.paired()) {
|
|
360
346
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
@@ -367,8 +353,8 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
367
353
|
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, 5 /* TLVErrorCode.MAX_TRIES */));
|
|
368
354
|
return;
|
|
369
355
|
}
|
|
370
|
-
|
|
371
|
-
|
|
356
|
+
const tlvData = tlv.decode(data);
|
|
357
|
+
const sequence = tlvData[6 /* TLVValues.SEQUENCE_NUM */][0]; // value is single byte with sequence number
|
|
372
358
|
if (sequence === 1 /* PairingStates.M1 */) {
|
|
373
359
|
this.handlePairSetupM1(connection, request, response);
|
|
374
360
|
}
|
|
@@ -384,34 +370,33 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
384
370
|
response.end(tlv.encode(6 /* TLVValues.STATE */, sequence + 1, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
385
371
|
return;
|
|
386
372
|
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
var _this = this;
|
|
373
|
+
}
|
|
374
|
+
handlePairSetupM1(connection, request, response) {
|
|
390
375
|
debug("[%s] Pair step 1/5", this.accessoryInfo.username);
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
fast_srp_hap_1.SRP.genKey(32).then(
|
|
376
|
+
const salt = crypto_1.default.randomBytes(16);
|
|
377
|
+
const srpParams = fast_srp_hap_1.SRP.params.hap;
|
|
378
|
+
fast_srp_hap_1.SRP.genKey(32).then(key => {
|
|
394
379
|
// create a new SRP server
|
|
395
|
-
|
|
396
|
-
|
|
380
|
+
const srpServer = new fast_srp_hap_1.SrpServer(srpParams, salt, Buffer.from("Pair-Setup"), Buffer.from(this.accessoryInfo.pincode), key);
|
|
381
|
+
const srpB = srpServer.computeB();
|
|
397
382
|
// attach it to the current TCP session
|
|
398
383
|
connection.srpServer = srpServer;
|
|
399
384
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
400
385
|
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 2 /* PairingStates.M2 */, 2 /* TLVValues.SALT */, salt, 3 /* TLVValues.PUBLIC_KEY */, srpB));
|
|
401
386
|
connection._pairSetupState = 2 /* PairingStates.M2 */;
|
|
402
|
-
}).catch(
|
|
403
|
-
debug("[%s] Error occurred when generating srp key: %s",
|
|
387
|
+
}).catch(error => {
|
|
388
|
+
debug("[%s] Error occurred when generating srp key: %s", this.accessoryInfo.username, error.message);
|
|
404
389
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
405
390
|
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
406
391
|
return;
|
|
407
392
|
});
|
|
408
|
-
}
|
|
409
|
-
|
|
393
|
+
}
|
|
394
|
+
handlePairSetupM3(connection, request, response, tlvData) {
|
|
410
395
|
debug("[%s] Pair step 2/5", this.accessoryInfo.username);
|
|
411
|
-
|
|
412
|
-
|
|
396
|
+
const A = tlvData[3 /* TLVValues.PUBLIC_KEY */]; // "A is a public key that exists only for a single login session."
|
|
397
|
+
const M1 = tlvData[4 /* TLVValues.PASSWORD_PROOF */]; // "M1 is the proof that you actually know your own password."
|
|
413
398
|
// pull the SRP server we created in stepOne out of the current session
|
|
414
|
-
|
|
399
|
+
const srpServer = connection.srpServer;
|
|
415
400
|
srpServer.setA(A);
|
|
416
401
|
try {
|
|
417
402
|
srpServer.checkM1(M1);
|
|
@@ -426,25 +411,25 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
426
411
|
return;
|
|
427
412
|
}
|
|
428
413
|
// "M2 is the proof that the server actually knows your password."
|
|
429
|
-
|
|
414
|
+
const M2 = srpServer.computeM2();
|
|
430
415
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
431
416
|
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 4 /* PairingStates.M4 */, 4 /* TLVValues.PASSWORD_PROOF */, M2));
|
|
432
417
|
connection._pairSetupState = 4 /* PairingStates.M4 */;
|
|
433
|
-
}
|
|
434
|
-
|
|
418
|
+
}
|
|
419
|
+
handlePairSetupM5(connection, request, response, tlvData) {
|
|
435
420
|
debug("[%s] Pair step 3/5", this.accessoryInfo.username);
|
|
436
421
|
// pull the SRP server we created in stepOne out of the current session
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
422
|
+
const srpServer = connection.srpServer;
|
|
423
|
+
const encryptedData = tlvData[5 /* TLVValues.ENCRYPTED_DATA */];
|
|
424
|
+
const messageData = Buffer.alloc(encryptedData.length - 16);
|
|
425
|
+
const authTagData = Buffer.alloc(16);
|
|
441
426
|
encryptedData.copy(messageData, 0, 0, encryptedData.length - 16);
|
|
442
427
|
encryptedData.copy(authTagData, 0, encryptedData.length - 16, encryptedData.length);
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
428
|
+
const S_private = srpServer.computeK();
|
|
429
|
+
const encSalt = Buffer.from("Pair-Setup-Encrypt-Salt");
|
|
430
|
+
const encInfo = Buffer.from("Pair-Setup-Encrypt-Info");
|
|
431
|
+
const outputKey = hapCrypto.HKDF("sha512", encSalt, S_private, encInfo, 32);
|
|
432
|
+
let plaintext;
|
|
448
433
|
try {
|
|
449
434
|
plaintext = hapCrypto.chacha20_poly1305_decryptAndVerify(outputKey, Buffer.from("PS-Msg05"), null, messageData, authTagData);
|
|
450
435
|
}
|
|
@@ -456,20 +441,20 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
456
441
|
return;
|
|
457
442
|
}
|
|
458
443
|
// decode the client payload and pass it on to the next step
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
444
|
+
const M5Packet = tlv.decode(plaintext);
|
|
445
|
+
const clientUsername = M5Packet[1 /* TLVValues.USERNAME */];
|
|
446
|
+
const clientLTPK = M5Packet[3 /* TLVValues.PUBLIC_KEY */];
|
|
447
|
+
const clientProof = M5Packet[10 /* TLVValues.PROOF */];
|
|
463
448
|
this.handlePairSetupM5_2(connection, request, response, clientUsername, clientLTPK, clientProof, outputKey);
|
|
464
|
-
}
|
|
449
|
+
}
|
|
465
450
|
// M5-2
|
|
466
|
-
|
|
451
|
+
handlePairSetupM5_2(connection, request, response, clientUsername, clientLTPK, clientProof, hkdfEncKey) {
|
|
467
452
|
debug("[%s] Pair step 4/5", this.accessoryInfo.username);
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
453
|
+
const S_private = connection.srpServer.computeK();
|
|
454
|
+
const controllerSalt = Buffer.from("Pair-Setup-Controller-Sign-Salt");
|
|
455
|
+
const controllerInfo = Buffer.from("Pair-Setup-Controller-Sign-Info");
|
|
456
|
+
const outputKey = hapCrypto.HKDF("sha512", controllerSalt, S_private, controllerInfo, 32);
|
|
457
|
+
const completeData = Buffer.concat([outputKey, clientUsername, clientLTPK]);
|
|
473
458
|
if (!tweetnacl_1.default.sign.detached.verify(completeData, clientProof, clientLTPK)) {
|
|
474
459
|
debug("[%s] Invalid signature", this.accessoryInfo.username);
|
|
475
460
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
@@ -478,26 +463,25 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
478
463
|
return;
|
|
479
464
|
}
|
|
480
465
|
this.handlePairSetupM5_3(connection, request, response, clientUsername, clientLTPK, hkdfEncKey);
|
|
481
|
-
}
|
|
466
|
+
}
|
|
482
467
|
// M5 - F + M6
|
|
483
|
-
|
|
484
|
-
var _this = this;
|
|
468
|
+
handlePairSetupM5_3(connection, request, response, clientUsername, clientLTPK, hkdfEncKey) {
|
|
485
469
|
debug("[%s] Pair step 5/5", this.accessoryInfo.username);
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
470
|
+
const S_private = connection.srpServer.computeK();
|
|
471
|
+
const accessorySalt = Buffer.from("Pair-Setup-Accessory-Sign-Salt");
|
|
472
|
+
const accessoryInfo = Buffer.from("Pair-Setup-Accessory-Sign-Info");
|
|
473
|
+
const outputKey = hapCrypto.HKDF("sha512", accessorySalt, S_private, accessoryInfo, 32);
|
|
474
|
+
const serverLTPK = this.accessoryInfo.signPk;
|
|
475
|
+
const usernameData = Buffer.from(this.accessoryInfo.username);
|
|
476
|
+
const material = Buffer.concat([outputKey, usernameData, serverLTPK]);
|
|
477
|
+
const privateKey = Buffer.from(this.accessoryInfo.signSk);
|
|
478
|
+
const serverProof = tweetnacl_1.default.sign.detached(material, privateKey);
|
|
479
|
+
const message = tlv.encode(1 /* TLVValues.USERNAME */, usernameData, 3 /* TLVValues.PUBLIC_KEY */, serverLTPK, 10 /* TLVValues.PROOF */, serverProof);
|
|
480
|
+
const encrypted = hapCrypto.chacha20_poly1305_encryptAndSeal(hkdfEncKey, Buffer.from("PS-Msg06"), null, message);
|
|
497
481
|
// finally, notify listeners that we have been paired with a client
|
|
498
|
-
this.emit("pair" /* HAPServerEventTypes.PAIR */, clientUsername.toString(), clientLTPK, (0, once_1.once)(
|
|
482
|
+
this.emit("pair" /* HAPServerEventTypes.PAIR */, clientUsername.toString(), clientLTPK, (0, once_1.once)(err => {
|
|
499
483
|
if (err) {
|
|
500
|
-
debug("[%s] Error adding pairing info: %s",
|
|
484
|
+
debug("[%s] Error adding pairing info: %s", this.accessoryInfo.username, err.message);
|
|
501
485
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
502
486
|
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 6 /* PairingStates.M6 */, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
503
487
|
connection._pairSetupState = undefined;
|
|
@@ -508,10 +492,10 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
508
492
|
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 6 /* PairingStates.M6 */, 5 /* TLVValues.ENCRYPTED_DATA */, Buffer.concat([encrypted.ciphertext, encrypted.authTag])));
|
|
509
493
|
connection._pairSetupState = undefined;
|
|
510
494
|
}));
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
495
|
+
}
|
|
496
|
+
handlePairVerify(connection, url, request, data, response) {
|
|
497
|
+
const tlvData = tlv.decode(data);
|
|
498
|
+
const sequence = tlvData[6 /* TLVValues.SEQUENCE_NUM */][0]; // value is single byte with sequence number
|
|
515
499
|
if (sequence === 1 /* PairingStates.M1 */) {
|
|
516
500
|
this.handlePairVerifyM1(connection, request, response, tlvData);
|
|
517
501
|
}
|
|
@@ -524,40 +508,40 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
524
508
|
response.end(tlv.encode(6 /* TLVValues.STATE */, sequence + 1, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
525
509
|
return;
|
|
526
510
|
}
|
|
527
|
-
}
|
|
528
|
-
|
|
511
|
+
}
|
|
512
|
+
handlePairVerifyM1(connection, request, response, tlvData) {
|
|
529
513
|
debug("[%s] Pair verify step 1/2", this.accessoryInfo.username);
|
|
530
|
-
|
|
514
|
+
const clientPublicKey = tlvData[3 /* TLVValues.PUBLIC_KEY */]; // Buffer
|
|
531
515
|
// generate new encryption keys for this session
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
516
|
+
const keyPair = hapCrypto.generateCurve25519KeyPair();
|
|
517
|
+
const secretKey = Buffer.from(keyPair.secretKey);
|
|
518
|
+
const publicKey = Buffer.from(keyPair.publicKey);
|
|
519
|
+
const sharedSec = Buffer.from(hapCrypto.generateCurve25519SharedSecKey(secretKey, clientPublicKey));
|
|
520
|
+
const usernameData = Buffer.from(this.accessoryInfo.username);
|
|
521
|
+
const material = Buffer.concat([publicKey, usernameData, clientPublicKey]);
|
|
522
|
+
const privateKey = Buffer.from(this.accessoryInfo.signSk);
|
|
523
|
+
const serverProof = tweetnacl_1.default.sign.detached(material, privateKey);
|
|
524
|
+
const encSalt = Buffer.from("Pair-Verify-Encrypt-Salt");
|
|
525
|
+
const encInfo = Buffer.from("Pair-Verify-Encrypt-Info");
|
|
526
|
+
const outputKey = hapCrypto.HKDF("sha512", encSalt, sharedSec, encInfo, 32).slice(0, 32);
|
|
543
527
|
connection.encryption = new eventedhttp_1.HAPEncryption(clientPublicKey, secretKey, publicKey, sharedSec, outputKey);
|
|
544
528
|
// compose the response data in TLV format
|
|
545
|
-
|
|
546
|
-
|
|
529
|
+
const message = tlv.encode(1 /* TLVValues.USERNAME */, usernameData, 10 /* TLVValues.PROOF */, serverProof);
|
|
530
|
+
const encrypted = hapCrypto.chacha20_poly1305_encryptAndSeal(outputKey, Buffer.from("PV-Msg02"), null, message);
|
|
547
531
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
548
532
|
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 2 /* PairingStates.M2 */, 5 /* TLVValues.ENCRYPTED_DATA */, Buffer.concat([encrypted.ciphertext, encrypted.authTag]), 3 /* TLVValues.PUBLIC_KEY */, publicKey));
|
|
549
533
|
connection._pairVerifyState = 2 /* PairingStates.M2 */;
|
|
550
|
-
}
|
|
551
|
-
|
|
534
|
+
}
|
|
535
|
+
handlePairVerifyM3(connection, request, response, objects) {
|
|
552
536
|
debug("[%s] Pair verify step 2/2", this.accessoryInfo.username);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
537
|
+
const encryptedData = objects[5 /* TLVValues.ENCRYPTED_DATA */];
|
|
538
|
+
const messageData = Buffer.alloc(encryptedData.length - 16);
|
|
539
|
+
const authTagData = Buffer.alloc(16);
|
|
556
540
|
encryptedData.copy(messageData, 0, 0, encryptedData.length - 16);
|
|
557
541
|
encryptedData.copy(authTagData, 0, encryptedData.length - 16, encryptedData.length);
|
|
558
542
|
// instance of HAPEncryption (created in handlePairVerifyStepOne)
|
|
559
|
-
|
|
560
|
-
|
|
543
|
+
const enc = connection.encryption;
|
|
544
|
+
let plaintext;
|
|
561
545
|
try {
|
|
562
546
|
plaintext = hapCrypto.chacha20_poly1305_decryptAndVerify(enc.hkdfPairEncryptionKey, Buffer.from("PV-Msg03"), null, messageData, authTagData);
|
|
563
547
|
}
|
|
@@ -568,12 +552,12 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
568
552
|
connection._pairVerifyState = undefined;
|
|
569
553
|
return;
|
|
570
554
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
555
|
+
const decoded = tlv.decode(plaintext);
|
|
556
|
+
const clientUsername = decoded[1 /* TLVValues.USERNAME */];
|
|
557
|
+
const proof = decoded[10 /* TLVValues.PROOF */];
|
|
558
|
+
const material = Buffer.concat([enc.clientPublicKey, clientUsername, enc.publicKey]);
|
|
575
559
|
// since we're paired, we should have the public key stored for this client
|
|
576
|
-
|
|
560
|
+
const clientPublicKey = this.accessoryInfo.getClientPublicKey(clientUsername.toString());
|
|
577
561
|
// if we're not actually paired, then there's nothing to verify - this client thinks it's paired with us, but we
|
|
578
562
|
// disagree. Respond with invalid request (seems to match HomeKit Accessory Simulator behavior)
|
|
579
563
|
if (!clientPublicKey) {
|
|
@@ -596,90 +580,89 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
596
580
|
// now that the client has been verified, we must "upgrade" our pseudo-HTTP connection to include
|
|
597
581
|
// TCP-level encryption. We'll do this by adding some more encryption vars to the session, and using them
|
|
598
582
|
// in future calls to onEncrypt, onDecrypt.
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
583
|
+
const encSalt = Buffer.from("Control-Salt");
|
|
584
|
+
const infoRead = Buffer.from("Control-Read-Encryption-Key");
|
|
585
|
+
const infoWrite = Buffer.from("Control-Write-Encryption-Key");
|
|
602
586
|
enc.accessoryToControllerKey = hapCrypto.HKDF("sha512", encSalt, enc.sharedSecret, infoRead, 32);
|
|
603
587
|
enc.controllerToAccessoryKey = hapCrypto.HKDF("sha512", encSalt, enc.sharedSecret, infoWrite, 32);
|
|
604
588
|
// Our connection is now completely setup. We now want to subscribe this connection to special
|
|
605
589
|
connection.connectionAuthenticated(clientUsername.toString());
|
|
606
590
|
connection._pairVerifyState = undefined;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
var _this = this;
|
|
591
|
+
}
|
|
592
|
+
handlePairings(connection, url, request, data, response) {
|
|
610
593
|
// Only accept /pairing request if there is a secure session
|
|
611
594
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
612
595
|
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
613
596
|
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
614
597
|
return;
|
|
615
598
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
599
|
+
const objects = tlv.decode(data);
|
|
600
|
+
const method = objects[0 /* TLVValues.METHOD */][0]; // value is single byte with request type
|
|
601
|
+
const state = objects[6 /* TLVValues.STATE */][0];
|
|
619
602
|
if (state !== 1 /* PairingStates.M1 */) {
|
|
620
603
|
return;
|
|
621
604
|
}
|
|
622
605
|
if (method === 3 /* PairMethods.ADD_PAIRING */) {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
this.emit("add-pairing" /* HAPServerEventTypes.ADD_PAIRING */, connection, identifier, publicKey, permissions, (0, once_1.once)(
|
|
606
|
+
const identifier = objects[1 /* TLVValues.IDENTIFIER */].toString();
|
|
607
|
+
const publicKey = objects[3 /* TLVValues.PUBLIC_KEY */];
|
|
608
|
+
const permissions = objects[11 /* TLVValues.PERMISSIONS */][0];
|
|
609
|
+
this.emit("add-pairing" /* HAPServerEventTypes.ADD_PAIRING */, connection, identifier, publicKey, permissions, (0, once_1.once)((error) => {
|
|
627
610
|
if (error > 0) {
|
|
628
|
-
debug("[%s] Pairings: failed ADD_PAIRING with code %d",
|
|
611
|
+
debug("[%s] Pairings: failed ADD_PAIRING with code %d", this.accessoryInfo.username, error);
|
|
629
612
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
630
613
|
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, error));
|
|
631
614
|
return;
|
|
632
615
|
}
|
|
633
616
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
634
617
|
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */));
|
|
635
|
-
debug("[%s] Pairings: successfully executed ADD_PAIRING",
|
|
618
|
+
debug("[%s] Pairings: successfully executed ADD_PAIRING", this.accessoryInfo.username);
|
|
636
619
|
}));
|
|
637
620
|
}
|
|
638
621
|
else if (method === 4 /* PairMethods.REMOVE_PAIRING */) {
|
|
639
|
-
|
|
640
|
-
this.emit("remove-pairing" /* HAPServerEventTypes.REMOVE_PAIRING */, connection, identifier, (0, once_1.once)(
|
|
622
|
+
const identifier = objects[1 /* TLVValues.IDENTIFIER */].toString();
|
|
623
|
+
this.emit("remove-pairing" /* HAPServerEventTypes.REMOVE_PAIRING */, connection, identifier, (0, once_1.once)((error) => {
|
|
641
624
|
if (error > 0) {
|
|
642
|
-
debug("[%s] Pairings: failed REMOVE_PAIRING with code %d",
|
|
625
|
+
debug("[%s] Pairings: failed REMOVE_PAIRING with code %d", this.accessoryInfo.username, error);
|
|
643
626
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
644
627
|
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, error));
|
|
645
628
|
return;
|
|
646
629
|
}
|
|
647
630
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
648
631
|
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */));
|
|
649
|
-
debug("[%s] Pairings: successfully executed REMOVE_PAIRING",
|
|
632
|
+
debug("[%s] Pairings: successfully executed REMOVE_PAIRING", this.accessoryInfo.username);
|
|
650
633
|
}));
|
|
651
634
|
}
|
|
652
635
|
else if (method === 5 /* PairMethods.LIST_PAIRINGS */) {
|
|
653
|
-
this.emit("list-pairings" /* HAPServerEventTypes.LIST_PAIRINGS */, connection, (0, once_1.once)(
|
|
636
|
+
this.emit("list-pairings" /* HAPServerEventTypes.LIST_PAIRINGS */, connection, (0, once_1.once)((error, data) => {
|
|
654
637
|
if (error > 0) {
|
|
655
|
-
debug("[%s] Pairings: failed LIST_PAIRINGS with code %d",
|
|
638
|
+
debug("[%s] Pairings: failed LIST_PAIRINGS with code %d", this.accessoryInfo.username, error);
|
|
656
639
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
657
640
|
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, error));
|
|
658
641
|
return;
|
|
659
642
|
}
|
|
660
643
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
661
|
-
|
|
662
|
-
data.forEach(
|
|
644
|
+
const tlvList = [];
|
|
645
|
+
data.forEach((value, index) => {
|
|
663
646
|
if (index > 0) {
|
|
664
647
|
tlvList.push(255 /* TLVValues.SEPARATOR */, Buffer.alloc(0));
|
|
665
648
|
}
|
|
666
649
|
tlvList.push(1 /* TLVValues.IDENTIFIER */, value.username, 3 /* TLVValues.PUBLIC_KEY */, value.publicKey, 11 /* TLVValues.PERMISSIONS */, value.permission);
|
|
667
650
|
});
|
|
668
|
-
|
|
651
|
+
const list = tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, ...tlvList);
|
|
669
652
|
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" /* HAPMimeTypes.PAIRING_TLV8 */ });
|
|
670
653
|
response.end(list);
|
|
671
|
-
debug("[%s] Pairings: successfully executed LIST_PAIRINGS",
|
|
654
|
+
debug("[%s] Pairings: successfully executed LIST_PAIRINGS", this.accessoryInfo.username);
|
|
672
655
|
}));
|
|
673
656
|
}
|
|
674
|
-
}
|
|
675
|
-
|
|
657
|
+
}
|
|
658
|
+
handleAccessories(connection, url, request, data, response) {
|
|
676
659
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
677
660
|
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
678
661
|
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
679
662
|
return;
|
|
680
663
|
}
|
|
681
664
|
// call out to listeners to retrieve the latest accessories JSON
|
|
682
|
-
this.emit("accessories" /* HAPServerEventTypes.ACCESSORIES */, connection, (0, once_1.once)(
|
|
665
|
+
this.emit("accessories" /* HAPServerEventTypes.ACCESSORIES */, connection, (0, once_1.once)((error, result) => {
|
|
683
666
|
if (error) {
|
|
684
667
|
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
685
668
|
response.end(JSON.stringify({ status: error.status }));
|
|
@@ -689,87 +672,55 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
689
672
|
response.end(JSON.stringify(result));
|
|
690
673
|
}
|
|
691
674
|
}));
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
var e_1, _a;
|
|
675
|
+
}
|
|
676
|
+
handleCharacteristics(connection, url, request, data, response) {
|
|
695
677
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
696
678
|
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
697
679
|
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
698
680
|
return;
|
|
699
681
|
}
|
|
700
682
|
if (request.method === "GET") {
|
|
701
|
-
|
|
702
|
-
|
|
683
|
+
const searchParams = url.searchParams;
|
|
684
|
+
const idParam = searchParams.get("id");
|
|
703
685
|
if (!idParam) {
|
|
704
686
|
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
705
687
|
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
706
688
|
return;
|
|
707
689
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
iid: parseInt(split[1], 10), // (characteristic) instance id
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
720
|
-
finally {
|
|
721
|
-
try {
|
|
722
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
723
|
-
}
|
|
724
|
-
finally { if (e_1) throw e_1.error; }
|
|
690
|
+
const ids = [];
|
|
691
|
+
for (const entry of idParam.split(",")) { // ["1.9","2.14"]
|
|
692
|
+
const split = entry.split("."); // ["1","9"]
|
|
693
|
+
ids.push({
|
|
694
|
+
aid: parseInt(split[0], 10), // accessory id
|
|
695
|
+
iid: parseInt(split[1], 10), // (characteristic) instance id
|
|
696
|
+
});
|
|
725
697
|
}
|
|
726
|
-
|
|
698
|
+
const readRequest = {
|
|
727
699
|
ids: ids,
|
|
728
700
|
includeMeta: (0, internal_types_1.consideredTrue)(searchParams.get("meta")),
|
|
729
701
|
includePerms: (0, internal_types_1.consideredTrue)(searchParams.get("perms")),
|
|
730
702
|
includeType: (0, internal_types_1.consideredTrue)(searchParams.get("type")),
|
|
731
703
|
includeEvent: (0, internal_types_1.consideredTrue)(searchParams.get("ev")),
|
|
732
704
|
};
|
|
733
|
-
this.emit("get-characteristics" /* HAPServerEventTypes.GET_CHARACTERISTICS */, connection, readRequest, (0, once_1.once)(
|
|
734
|
-
var e_2, _a, e_3, _b;
|
|
705
|
+
this.emit("get-characteristics" /* HAPServerEventTypes.GET_CHARACTERISTICS */, connection, readRequest, (0, once_1.once)((error, readResponse) => {
|
|
735
706
|
if (error) {
|
|
736
707
|
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
737
708
|
response.end(JSON.stringify({ status: error.status }));
|
|
738
709
|
return;
|
|
739
710
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
errorOccurred = true;
|
|
747
|
-
break;
|
|
748
|
-
}
|
|
711
|
+
const characteristics = readResponse.characteristics;
|
|
712
|
+
let errorOccurred = false; // determine if we send a 207 Multi-Status
|
|
713
|
+
for (const data of characteristics) {
|
|
714
|
+
if (data.status) {
|
|
715
|
+
errorOccurred = true;
|
|
716
|
+
break;
|
|
749
717
|
}
|
|
750
718
|
}
|
|
751
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
752
|
-
finally {
|
|
753
|
-
try {
|
|
754
|
-
if (characteristics_1_1 && !characteristics_1_1.done && (_a = characteristics_1.return)) _a.call(characteristics_1);
|
|
755
|
-
}
|
|
756
|
-
finally { if (e_2) throw e_2.error; }
|
|
757
|
-
}
|
|
758
719
|
if (errorOccurred) { // on a 207 Multi-Status EVERY characteristic MUST include a status property
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
if (!data_2.status) { // a status is undefined if the request was successful
|
|
763
|
-
data_2.status = 0 /* HAPStatus.SUCCESS */; // a value of zero indicates success
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
768
|
-
finally {
|
|
769
|
-
try {
|
|
770
|
-
if (characteristics_2_1 && !characteristics_2_1.done && (_b = characteristics_2.return)) _b.call(characteristics_2);
|
|
720
|
+
for (const data of characteristics) {
|
|
721
|
+
if (!data.status) { // a status is undefined if the request was successful
|
|
722
|
+
data.status = 0 /* HAPStatus.SUCCESS */; // a value of zero indicates success
|
|
771
723
|
}
|
|
772
|
-
finally { if (e_3) throw e_3.error; }
|
|
773
724
|
}
|
|
774
725
|
}
|
|
775
726
|
// 207 "multi-status" is returned when an error occurs reading a characteristic. otherwise 200 is returned
|
|
@@ -790,33 +741,22 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
790
741
|
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
791
742
|
return;
|
|
792
743
|
}
|
|
793
|
-
|
|
794
|
-
this.emit("set-characteristics" /* HAPServerEventTypes.SET_CHARACTERISTICS */, connection, writeRequest, (0, once_1.once)(
|
|
795
|
-
var e_4, _a;
|
|
744
|
+
const writeRequest = JSON.parse(data.toString("utf8"));
|
|
745
|
+
this.emit("set-characteristics" /* HAPServerEventTypes.SET_CHARACTERISTICS */, connection, writeRequest, (0, once_1.once)((error, writeResponse) => {
|
|
796
746
|
if (error) {
|
|
797
747
|
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
798
748
|
response.end(JSON.stringify({ status: error.status }));
|
|
799
749
|
return;
|
|
800
750
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
multiStatus = true;
|
|
809
|
-
break;
|
|
810
|
-
}
|
|
751
|
+
const characteristics = writeResponse.characteristics;
|
|
752
|
+
let multiStatus = false;
|
|
753
|
+
for (const data of characteristics) {
|
|
754
|
+
if (data.status || data.value !== undefined) {
|
|
755
|
+
// also send multiStatus on write response requests
|
|
756
|
+
multiStatus = true;
|
|
757
|
+
break;
|
|
811
758
|
}
|
|
812
759
|
}
|
|
813
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
814
|
-
finally {
|
|
815
|
-
try {
|
|
816
|
-
if (characteristics_3_1 && !characteristics_3_1.done && (_a = characteristics_3.return)) _a.call(characteristics_3);
|
|
817
|
-
}
|
|
818
|
-
finally { if (e_4) throw e_4.error; }
|
|
819
|
-
}
|
|
820
760
|
if (multiStatus) {
|
|
821
761
|
// 207 is "multi-status" since HomeKit may be setting multiple things and any one can fail independently
|
|
822
762
|
response.writeHead(207 /* HAPHTTPCode.MULTI_STATUS */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
@@ -833,9 +773,8 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
833
773
|
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ }); // method not allowed
|
|
834
774
|
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
835
775
|
}
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
var _this = this;
|
|
776
|
+
}
|
|
777
|
+
handlePrepareWrite(connection, url, request, data, response) {
|
|
839
778
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
840
779
|
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
841
780
|
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
@@ -847,18 +786,18 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
847
786
|
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
848
787
|
return;
|
|
849
788
|
}
|
|
850
|
-
|
|
851
|
-
if (
|
|
852
|
-
debug("[%s] Received prepare write request with pid %d and ttl %d", this.accessoryInfo.username,
|
|
789
|
+
const prepareRequest = JSON.parse(data.toString());
|
|
790
|
+
if (prepareRequest.pid && prepareRequest.ttl) {
|
|
791
|
+
debug("[%s] Received prepare write request with pid %d and ttl %d", this.accessoryInfo.username, prepareRequest.pid, prepareRequest.ttl);
|
|
853
792
|
if (connection.timedWriteTimeout) { // clear any currently existing timeouts
|
|
854
793
|
clearTimeout(connection.timedWriteTimeout);
|
|
855
794
|
}
|
|
856
|
-
connection.timedWritePid =
|
|
857
|
-
connection.timedWriteTimeout = setTimeout(
|
|
858
|
-
debug("[%s] Timed write request timed out for pid %d",
|
|
795
|
+
connection.timedWritePid = prepareRequest.pid;
|
|
796
|
+
connection.timedWriteTimeout = setTimeout(() => {
|
|
797
|
+
debug("[%s] Timed write request timed out for pid %d", this.accessoryInfo.username, prepareRequest.pid);
|
|
859
798
|
connection.timedWritePid = undefined;
|
|
860
799
|
connection.timedWriteTimeout = undefined;
|
|
861
|
-
},
|
|
800
|
+
}, prepareRequest.ttl);
|
|
862
801
|
response.writeHead(200 /* HAPHTTPCode.OK */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
863
802
|
response.end(JSON.stringify({ status: 0 /* HAPStatus.SUCCESS */ }));
|
|
864
803
|
return;
|
|
@@ -872,8 +811,8 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
872
811
|
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
873
812
|
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
874
813
|
}
|
|
875
|
-
}
|
|
876
|
-
|
|
814
|
+
}
|
|
815
|
+
handleResource(connection, url, request, data, response) {
|
|
877
816
|
if (!connection.isAuthenticated()) {
|
|
878
817
|
if (!(this.allowInsecureRequest && request.headers && request.headers.authorization === this.accessoryInfo.pincode)) {
|
|
879
818
|
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
@@ -887,9 +826,9 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
887
826
|
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
888
827
|
return;
|
|
889
828
|
}
|
|
890
|
-
|
|
829
|
+
const resourceRequest = JSON.parse(data.toString());
|
|
891
830
|
// call out to listeners to retrieve the resource, snapshot only right now
|
|
892
|
-
this.emit("request-resource" /* HAPServerEventTypes.REQUEST_RESOURCE */, resourceRequest, (0, once_1.once)(
|
|
831
|
+
this.emit("request-resource" /* HAPServerEventTypes.REQUEST_RESOURCE */, resourceRequest, (0, once_1.once)((error, resource) => {
|
|
893
832
|
if (error) {
|
|
894
833
|
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
895
834
|
response.end(JSON.stringify({ status: error.status }));
|
|
@@ -904,8 +843,7 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
904
843
|
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ }); // method not allowed
|
|
905
844
|
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
906
845
|
}
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
}(events_1.EventEmitter));
|
|
846
|
+
}
|
|
847
|
+
}
|
|
910
848
|
exports.HAPServer = HAPServer;
|
|
911
849
|
//# sourceMappingURL=HAPServer.js.map
|