hap-nodejs 1.0.0-beta.2 → 1.0.0-beta.4
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/@types/bonjour-hap.d.ts +4 -3
- package/@types/simple-plist.d.ts +2 -1
- package/README.md +2 -1
- package/dist/BridgedCore.js +7 -5
- package/dist/BridgedCore.js.map +1 -1
- package/dist/Core.js +14 -8
- package/dist/Core.js.map +1 -1
- package/dist/accessories/AirConditioner_accessory.d.ts +2 -0
- package/dist/accessories/AirConditioner_accessory.d.ts.map +1 -0
- package/dist/accessories/AirConditioner_accessory.js +128 -0
- package/dist/accessories/AirConditioner_accessory.js.map +1 -0
- package/dist/accessories/AppleTVRemote_accessory.d.ts +2 -0
- package/dist/accessories/AppleTVRemote_accessory.d.ts.map +1 -0
- package/dist/accessories/AppleTVRemote_accessory.js +159 -0
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -0
- package/dist/accessories/Camera_accessory.d.ts +2 -0
- package/dist/accessories/Camera_accessory.d.ts.map +1 -0
- package/dist/accessories/Camera_accessory.js +630 -0
- package/dist/accessories/Camera_accessory.js.map +1 -0
- package/dist/accessories/Fan_accessory.d.ts +2 -0
- package/dist/accessories/Fan_accessory.d.ts.map +1 -0
- package/dist/accessories/Fan_accessory.js +80 -0
- package/dist/accessories/Fan_accessory.js.map +1 -0
- package/dist/accessories/GarageDoorOpener_accessory.d.ts +2 -0
- package/dist/accessories/GarageDoorOpener_accessory.d.ts.map +1 -0
- package/dist/accessories/GarageDoorOpener_accessory.js +78 -0
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -0
- package/dist/accessories/Light-AdaptiveLighting_accessory.d.ts +2 -0
- package/dist/accessories/Light-AdaptiveLighting_accessory.d.ts.map +1 -0
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +96 -0
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -0
- package/dist/accessories/Light_accessory.d.ts +2 -0
- package/dist/accessories/Light_accessory.d.ts.map +1 -0
- package/dist/accessories/Light_accessory.js +148 -0
- package/dist/accessories/Light_accessory.js.map +1 -0
- package/dist/accessories/Lock_accessory.d.ts +2 -0
- package/dist/accessories/Lock_accessory.d.ts.map +1 -0
- package/dist/accessories/Lock_accessory.js +76 -0
- package/dist/accessories/Lock_accessory.js.map +1 -0
- package/dist/accessories/MotionSensor_accessory.d.ts +2 -0
- package/dist/accessories/MotionSensor_accessory.d.ts.map +1 -0
- package/dist/accessories/MotionSensor_accessory.js +45 -0
- package/dist/accessories/MotionSensor_accessory.js.map +1 -0
- package/dist/accessories/Outlet_accessory.d.ts +2 -0
- package/dist/accessories/Outlet_accessory.d.ts.map +1 -0
- package/dist/accessories/Outlet_accessory.js +79 -0
- package/dist/accessories/Outlet_accessory.js.map +1 -0
- package/dist/accessories/SmartSpeaker_accessory.d.ts +2 -0
- package/dist/accessories/SmartSpeaker_accessory.d.ts.map +1 -0
- package/dist/accessories/SmartSpeaker_accessory.js +44 -0
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -0
- package/dist/accessories/Sprinkler_accessory.d.ts +2 -0
- package/dist/accessories/Sprinkler_accessory.d.ts.map +1 -0
- package/dist/accessories/Sprinkler_accessory.js +128 -0
- package/dist/accessories/Sprinkler_accessory.js.map +1 -0
- package/dist/accessories/TV_accessory.d.ts +2 -0
- package/dist/accessories/TV_accessory.d.ts.map +1 -0
- package/dist/accessories/TV_accessory.js +101 -0
- package/dist/accessories/TV_accessory.js.map +1 -0
- package/dist/accessories/TemperatureSensor_accessory.d.ts +2 -0
- package/dist/accessories/TemperatureSensor_accessory.d.ts.map +1 -0
- package/dist/accessories/TemperatureSensor_accessory.js +44 -0
- package/dist/accessories/TemperatureSensor_accessory.js.map +1 -0
- package/dist/accessories/Wi-FiRouter_accessory.d.ts +3 -0
- package/dist/accessories/Wi-FiRouter_accessory.d.ts.map +1 -0
- package/dist/accessories/Wi-FiRouter_accessory.js +17 -0
- package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -0
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts +3 -0
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts.map +1 -0
- package/dist/accessories/Wi-FiSatellite_accessory.js +19 -0
- package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -0
- package/dist/accessories/gstreamer-audioProducer.d.ts +25 -0
- package/dist/accessories/gstreamer-audioProducer.d.ts.map +1 -0
- package/dist/accessories/gstreamer-audioProducer.js +155 -0
- package/dist/accessories/gstreamer-audioProducer.js.map +1 -0
- package/dist/accessories/types.d.ts +78 -0
- package/dist/accessories/types.d.ts.map +1 -0
- package/dist/accessories/types.js +88 -0
- package/dist/accessories/types.js.map +1 -0
- package/dist/index.d.ts +54 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -11
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +65 -124
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/internal-types.js +66 -5
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +147 -60
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +566 -475
- package/dist/lib/Accessory.js.map +1 -1
- package/dist/lib/AccessoryLoader.d.ts +20 -8
- package/dist/lib/AccessoryLoader.d.ts.map +1 -1
- package/dist/lib/AccessoryLoader.js +115 -93
- package/dist/lib/AccessoryLoader.js.map +1 -1
- package/dist/lib/Advertiser.d.ts +99 -5
- package/dist/lib/Advertiser.d.ts.map +1 -1
- package/dist/lib/Advertiser.js +564 -22
- package/dist/lib/Advertiser.js.map +1 -1
- package/dist/lib/Bridge.d.ts +3 -1
- package/dist/lib/Bridge.d.ts.map +1 -1
- package/dist/lib/Bridge.js +2 -0
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +918 -59
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +308 -257
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +114 -43
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +269 -405
- package/dist/lib/HAPServer.js.map +1 -1
- package/dist/lib/Service.d.ts +339 -15
- package/dist/lib/Service.d.ts.map +1 -1
- package/dist/lib/Service.js +59 -50
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/Camera.d.ts +15 -6
- package/dist/lib/camera/Camera.d.ts.map +1 -1
- package/dist/lib/camera/Camera.js +6 -3
- package/dist/lib/camera/Camera.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +24 -19
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +230 -207
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +202 -43
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +303 -189
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +326 -0
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -0
- package/dist/lib/camera/RecordingManagement.js +833 -0
- package/dist/lib/camera/RecordingManagement.js.map +1 -0
- package/dist/lib/camera/index.d.ts +4 -3
- package/dist/lib/camera/index.d.ts.map +1 -1
- package/dist/lib/camera/index.js +1 -0
- package/dist/lib/camera/index.js.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.d.ts +37 -11
- package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.js +101 -86
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +290 -12
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +403 -47
- package/dist/lib/controller/CameraController.js.map +1 -1
- package/dist/lib/controller/Controller.d.ts +31 -10
- package/dist/lib/controller/Controller.d.ts.map +1 -1
- package/dist/lib/controller/Controller.js +7 -0
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.d.ts +47 -1
- package/dist/lib/controller/DoorbellController.d.ts.map +1 -1
- package/dist/lib/controller/DoorbellController.js +65 -11
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +111 -42
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +228 -203
- package/dist/lib/controller/RemoteController.js.map +1 -1
- package/dist/lib/controller/index.d.ts +4 -4
- package/dist/lib/datastream/DataStreamManagement.d.ts +25 -19
- package/dist/lib/datastream/DataStreamManagement.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.js +42 -35
- package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
- package/dist/lib/datastream/DataStreamParser.d.ts +63 -24
- package/dist/lib/datastream/DataStreamParser.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamParser.js +133 -87
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +154 -50
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +242 -147
- package/dist/lib/datastream/DataStreamServer.js.map +1 -1
- package/dist/lib/datastream/index.d.ts +3 -3
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts +181 -0
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.js +968 -499
- package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts +58 -0
- package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.js +173 -6
- package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
- package/dist/lib/definitions/generate-definitions.d.ts +1 -0
- package/dist/lib/definitions/generate-definitions.d.ts.map +1 -1
- package/dist/lib/definitions/generate-definitions.js +29 -21
- 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 +62 -29
- package/dist/lib/definitions/generator-configuration.js.map +1 -1
- package/dist/lib/model/AccessoryInfo.d.ts +16 -13
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +88 -83
- package/dist/lib/model/AccessoryInfo.js.map +1 -1
- package/dist/lib/model/ControllerStorage.d.ts +3 -0
- package/dist/lib/model/ControllerStorage.d.ts.map +1 -1
- package/dist/lib/model/ControllerStorage.js +7 -4
- package/dist/lib/model/ControllerStorage.js.map +1 -1
- package/dist/lib/model/HAPStorage.d.ts +3 -0
- package/dist/lib/model/HAPStorage.d.ts.map +1 -1
- package/dist/lib/model/HAPStorage.js +4 -0
- package/dist/lib/model/HAPStorage.js.map +1 -1
- package/dist/lib/model/IdentifierCache.d.ts +12 -11
- package/dist/lib/model/IdentifierCache.d.ts.map +1 -1
- package/dist/lib/model/IdentifierCache.js +68 -65
- package/dist/lib/model/IdentifierCache.js.map +1 -1
- package/dist/lib/tv/AccessControlManagement.d.ts +12 -1
- package/dist/lib/tv/AccessControlManagement.d.ts.map +1 -1
- package/dist/lib/tv/AccessControlManagement.js +13 -5
- package/dist/lib/tv/AccessControlManagement.js.map +1 -1
- package/dist/lib/util/clone.d.ts +2 -1
- package/dist/lib/util/clone.d.ts.map +1 -1
- package/dist/lib/util/clone.js +2 -0
- package/dist/lib/util/clone.js.map +1 -1
- package/dist/lib/util/color-utils.d.ts +4 -1
- package/dist/lib/util/color-utils.d.ts.map +1 -1
- package/dist/lib/util/color-utils.js +5 -2
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +62 -22
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +245 -188
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +35 -7
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +84 -78
- package/dist/lib/util/hapCrypto.js.map +1 -1
- package/dist/lib/util/hapStatusError.d.ts +2 -0
- package/dist/lib/util/hapStatusError.d.ts.map +1 -1
- package/dist/lib/util/hapStatusError.js +5 -3
- package/dist/lib/util/hapStatusError.js.map +1 -1
- package/dist/lib/util/net-utils.d.ts +7 -0
- package/dist/lib/util/net-utils.d.ts.map +1 -1
- package/dist/lib/util/net-utils.js +14 -7
- package/dist/lib/util/net-utils.js.map +1 -1
- package/dist/lib/util/once.d.ts +6 -1
- package/dist/lib/util/once.d.ts.map +1 -1
- package/dist/lib/util/once.js +9 -3
- package/dist/lib/util/once.js.map +1 -1
- package/dist/lib/util/promise-utils.d.ts +15 -0
- package/dist/lib/util/promise-utils.d.ts.map +1 -0
- package/dist/lib/util/promise-utils.js +36 -0
- package/dist/lib/util/promise-utils.js.map +1 -0
- package/dist/lib/util/request-util.d.ts +16 -0
- package/dist/lib/util/request-util.d.ts.map +1 -1
- package/dist/lib/util/request-util.js +43 -27
- package/dist/lib/util/request-util.js.map +1 -1
- package/dist/lib/util/time.d.ts +7 -1
- package/dist/lib/util/time.d.ts.map +1 -1
- package/dist/lib/util/time.js +13 -7
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +95 -5
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +96 -24
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +2 -3
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +25 -19
- package/dist/lib/util/uuid.js.map +1 -1
- package/dist/types.d.ts +271 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/package.json +30 -29
- package/dist/lib/util/setupcode.d.ts +0 -5
- package/dist/lib/util/setupcode.d.ts.map +0 -1
- package/dist/lib/util/setupcode.js +0 -49
- package/dist/lib/util/setupcode.js.map +0 -1
- package/dist/lib/util/setupid.d.ts +0 -5
- package/dist/lib/util/setupid.d.ts.map +0 -1
- package/dist/lib/util/setupid.js +0 -52
- package/dist/lib/util/setupid.js.map +0 -1
package/dist/lib/HAPServer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HAPServer = exports.HAPServerEventTypes = exports.HAPPairingHTTPCode = exports.HAPHTTPCode = exports.Status = exports.Codes = exports.IsKnownHAPStatusError = exports.HAPStatus = exports.
|
|
3
|
+
exports.HAPServer = exports.HAPServerEventTypes = exports.HAPPairingHTTPCode = exports.HAPHTTPCode = exports.Status = exports.Codes = exports.IsKnownHAPStatusError = exports.HAPStatus = exports.TLVErrorCode = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
6
6
|
var debug_1 = tslib_1.__importDefault(require("debug"));
|
|
@@ -13,55 +13,11 @@ var eventedhttp_1 = require("./util/eventedhttp");
|
|
|
13
13
|
var hapCrypto = tslib_1.__importStar(require("./util/hapCrypto"));
|
|
14
14
|
var once_1 = require("./util/once");
|
|
15
15
|
var tlv = tslib_1.__importStar(require("./util/tlv"));
|
|
16
|
-
var debug = debug_1.default(
|
|
17
|
-
var TLVValues;
|
|
18
|
-
(function (TLVValues) {
|
|
19
|
-
// noinspection JSUnusedGlobalSymbols
|
|
20
|
-
TLVValues[TLVValues["REQUEST_TYPE"] = 0] = "REQUEST_TYPE";
|
|
21
|
-
TLVValues[TLVValues["METHOD"] = 0] = "METHOD";
|
|
22
|
-
TLVValues[TLVValues["USERNAME"] = 1] = "USERNAME";
|
|
23
|
-
TLVValues[TLVValues["IDENTIFIER"] = 1] = "IDENTIFIER";
|
|
24
|
-
TLVValues[TLVValues["SALT"] = 2] = "SALT";
|
|
25
|
-
TLVValues[TLVValues["PUBLIC_KEY"] = 3] = "PUBLIC_KEY";
|
|
26
|
-
TLVValues[TLVValues["PASSWORD_PROOF"] = 4] = "PASSWORD_PROOF";
|
|
27
|
-
TLVValues[TLVValues["ENCRYPTED_DATA"] = 5] = "ENCRYPTED_DATA";
|
|
28
|
-
TLVValues[TLVValues["SEQUENCE_NUM"] = 6] = "SEQUENCE_NUM";
|
|
29
|
-
TLVValues[TLVValues["STATE"] = 6] = "STATE";
|
|
30
|
-
TLVValues[TLVValues["ERROR_CODE"] = 7] = "ERROR_CODE";
|
|
31
|
-
TLVValues[TLVValues["RETRY_DELAY"] = 8] = "RETRY_DELAY";
|
|
32
|
-
TLVValues[TLVValues["CERTIFICATE"] = 9] = "CERTIFICATE";
|
|
33
|
-
TLVValues[TLVValues["PROOF"] = 10] = "PROOF";
|
|
34
|
-
TLVValues[TLVValues["SIGNATURE"] = 10] = "SIGNATURE";
|
|
35
|
-
TLVValues[TLVValues["PERMISSIONS"] = 11] = "PERMISSIONS";
|
|
36
|
-
TLVValues[TLVValues["FRAGMENT_DATA"] = 12] = "FRAGMENT_DATA";
|
|
37
|
-
TLVValues[TLVValues["FRAGMENT_LAST"] = 13] = "FRAGMENT_LAST";
|
|
38
|
-
TLVValues[TLVValues["FLAGS"] = 19] = "FLAGS";
|
|
39
|
-
TLVValues[TLVValues["SEPARATOR"] = 255] = "SEPARATOR"; // Zero-length TLV that separates different TLVs in a list.
|
|
40
|
-
})(TLVValues || (TLVValues = {}));
|
|
41
|
-
var PairMethods;
|
|
42
|
-
(function (PairMethods) {
|
|
43
|
-
// noinspection JSUnusedGlobalSymbols
|
|
44
|
-
PairMethods[PairMethods["PAIR_SETUP"] = 0] = "PAIR_SETUP";
|
|
45
|
-
PairMethods[PairMethods["PAIR_SETUP_WITH_AUTH"] = 1] = "PAIR_SETUP_WITH_AUTH";
|
|
46
|
-
PairMethods[PairMethods["PAIR_VERIFY"] = 2] = "PAIR_VERIFY";
|
|
47
|
-
PairMethods[PairMethods["ADD_PAIRING"] = 3] = "ADD_PAIRING";
|
|
48
|
-
PairMethods[PairMethods["REMOVE_PAIRING"] = 4] = "REMOVE_PAIRING";
|
|
49
|
-
PairMethods[PairMethods["LIST_PAIRINGS"] = 5] = "LIST_PAIRINGS";
|
|
50
|
-
})(PairMethods || (PairMethods = {}));
|
|
51
|
-
/**
|
|
52
|
-
* Pairing states (pair-setup or pair-verify). Encoded in {@link TLVValues.SEQUENCE_NUM}.
|
|
53
|
-
*/
|
|
54
|
-
var PairingStates;
|
|
55
|
-
(function (PairingStates) {
|
|
56
|
-
PairingStates[PairingStates["M1"] = 1] = "M1";
|
|
57
|
-
PairingStates[PairingStates["M2"] = 2] = "M2";
|
|
58
|
-
PairingStates[PairingStates["M3"] = 3] = "M3";
|
|
59
|
-
PairingStates[PairingStates["M4"] = 4] = "M4";
|
|
60
|
-
PairingStates[PairingStates["M5"] = 5] = "M5";
|
|
61
|
-
PairingStates[PairingStates["M6"] = 6] = "M6";
|
|
62
|
-
})(PairingStates || (PairingStates = {}));
|
|
16
|
+
var debug = (0, debug_1.default)("HAP-NodeJS:HAPServer");
|
|
63
17
|
/**
|
|
64
|
-
* TLV error codes for the
|
|
18
|
+
* TLV error codes for the `TLVValues.ERROR_CODE` field.
|
|
19
|
+
*
|
|
20
|
+
* @group HAP Accessory Server
|
|
65
21
|
*/
|
|
66
22
|
var TLVErrorCode;
|
|
67
23
|
(function (TLVErrorCode) {
|
|
@@ -75,48 +31,89 @@ var TLVErrorCode;
|
|
|
75
31
|
TLVErrorCode[TLVErrorCode["UNAVAILABLE"] = 6] = "UNAVAILABLE";
|
|
76
32
|
TLVErrorCode[TLVErrorCode["BUSY"] = 7] = "BUSY"; // cannot accept pairing request at this time
|
|
77
33
|
})(TLVErrorCode = exports.TLVErrorCode || (exports.TLVErrorCode = {}));
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
PairingFlags[PairingFlags["SPLIT"] = 16777216] = "SPLIT";
|
|
82
|
-
})(PairingFlags = exports.PairingFlags || (exports.PairingFlags = {}));
|
|
34
|
+
/**
|
|
35
|
+
* @group HAP Accessory Server
|
|
36
|
+
*/
|
|
83
37
|
var HAPStatus;
|
|
84
38
|
(function (HAPStatus) {
|
|
85
39
|
// noinspection JSUnusedGlobalSymbols
|
|
40
|
+
/**
|
|
41
|
+
* Success of the request.
|
|
42
|
+
*/
|
|
86
43
|
HAPStatus[HAPStatus["SUCCESS"] = 0] = "SUCCESS";
|
|
44
|
+
/**
|
|
45
|
+
* The request was rejected due to insufficient privileges.
|
|
46
|
+
*/
|
|
87
47
|
HAPStatus[HAPStatus["INSUFFICIENT_PRIVILEGES"] = -70401] = "INSUFFICIENT_PRIVILEGES";
|
|
48
|
+
/**
|
|
49
|
+
* Operation failed due to some communication failure with the characteristic.
|
|
50
|
+
*/
|
|
88
51
|
HAPStatus[HAPStatus["SERVICE_COMMUNICATION_FAILURE"] = -70402] = "SERVICE_COMMUNICATION_FAILURE";
|
|
52
|
+
/**
|
|
53
|
+
* The resource is busy. Try again.
|
|
54
|
+
*/
|
|
89
55
|
HAPStatus[HAPStatus["RESOURCE_BUSY"] = -70403] = "RESOURCE_BUSY";
|
|
56
|
+
/**
|
|
57
|
+
* Cannot write a read-only characteristic ({@link Perms.PAIRED_WRITE} not defined).
|
|
58
|
+
*/
|
|
90
59
|
HAPStatus[HAPStatus["READ_ONLY_CHARACTERISTIC"] = -70404] = "READ_ONLY_CHARACTERISTIC";
|
|
60
|
+
/**
|
|
61
|
+
* Cannot read from a write-only characteristic ({@link Perms.PAIRED_READ} not defined).
|
|
62
|
+
*/
|
|
91
63
|
HAPStatus[HAPStatus["WRITE_ONLY_CHARACTERISTIC"] = -70405] = "WRITE_ONLY_CHARACTERISTIC";
|
|
64
|
+
/**
|
|
65
|
+
* Event notifications are not supported for the requested characteristic ({@link Perms.NOTIFY} not defined).
|
|
66
|
+
*/
|
|
92
67
|
HAPStatus[HAPStatus["NOTIFICATION_NOT_SUPPORTED"] = -70406] = "NOTIFICATION_NOT_SUPPORTED";
|
|
68
|
+
/**
|
|
69
|
+
* The device is out of resources to process the request.
|
|
70
|
+
*/
|
|
93
71
|
HAPStatus[HAPStatus["OUT_OF_RESOURCE"] = -70407] = "OUT_OF_RESOURCE";
|
|
72
|
+
/**
|
|
73
|
+
* The operation timed out.
|
|
74
|
+
*/
|
|
94
75
|
HAPStatus[HAPStatus["OPERATION_TIMED_OUT"] = -70408] = "OPERATION_TIMED_OUT";
|
|
76
|
+
/**
|
|
77
|
+
* The given resource does not exist.
|
|
78
|
+
*/
|
|
95
79
|
HAPStatus[HAPStatus["RESOURCE_DOES_NOT_EXIST"] = -70409] = "RESOURCE_DOES_NOT_EXIST";
|
|
80
|
+
/**
|
|
81
|
+
* Received an invalid value in the given request for the given characteristic.
|
|
82
|
+
*/
|
|
96
83
|
HAPStatus[HAPStatus["INVALID_VALUE_IN_REQUEST"] = -70410] = "INVALID_VALUE_IN_REQUEST";
|
|
84
|
+
/**
|
|
85
|
+
* Insufficient authorization.
|
|
86
|
+
*/
|
|
97
87
|
HAPStatus[HAPStatus["INSUFFICIENT_AUTHORIZATION"] = -70411] = "INSUFFICIENT_AUTHORIZATION";
|
|
88
|
+
/**
|
|
89
|
+
* Operation not allowed in the current state.
|
|
90
|
+
*/
|
|
98
91
|
HAPStatus[HAPStatus["NOT_ALLOWED_IN_CURRENT_STATE"] = -70412] = "NOT_ALLOWED_IN_CURRENT_STATE";
|
|
99
92
|
// when adding new status codes, remember to update bounds in IsKnownHAPStatusError below
|
|
100
93
|
})(HAPStatus = exports.HAPStatus || (exports.HAPStatus = {}));
|
|
101
94
|
/**
|
|
102
95
|
* Determines if the given status code is a known {@link HAPStatus} error code.
|
|
96
|
+
*
|
|
97
|
+
* @group HAP Accessory Server
|
|
103
98
|
*/
|
|
104
99
|
function IsKnownHAPStatusError(status) {
|
|
105
100
|
return (
|
|
106
101
|
// Lower bound (most negative error code)
|
|
107
|
-
status >= -70412 /* NOT_ALLOWED_IN_CURRENT_STATE */ &&
|
|
102
|
+
status >= -70412 /* HAPStatus.NOT_ALLOWED_IN_CURRENT_STATE */ &&
|
|
108
103
|
// Upper bound (negative error code closest to zero)
|
|
109
|
-
status <= -70401 /* INSUFFICIENT_PRIVILEGES */);
|
|
104
|
+
status <= -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */);
|
|
110
105
|
}
|
|
111
106
|
exports.IsKnownHAPStatusError = IsKnownHAPStatusError;
|
|
112
107
|
// noinspection JSUnusedGlobalSymbols
|
|
113
108
|
/**
|
|
109
|
+
* @group HAP Accessory Server
|
|
114
110
|
* @deprecated please use {@link TLVErrorCode} as naming is more precise
|
|
115
111
|
*/
|
|
116
112
|
// @ts-expect-error (as we use const enums with --preserveConstEnums)
|
|
117
113
|
exports.Codes = TLVErrorCode;
|
|
118
114
|
// noinspection JSUnusedGlobalSymbols
|
|
119
115
|
/**
|
|
116
|
+
* @group HAP Accessory Server
|
|
120
117
|
* @deprecated please use {@link HAPStatus} as naming is more precise
|
|
121
118
|
*/
|
|
122
119
|
// @ts-expect-error (as we use const enums with --preserveConstEnums)
|
|
@@ -128,6 +125,8 @@ exports.Status = HAPStatus;
|
|
|
128
125
|
* must include a status {@link HAPStatus} property.
|
|
129
126
|
*
|
|
130
127
|
* When the response is a MULTI_STATUS EVERY entry in the characteristics property MUST include a status property (even success).
|
|
128
|
+
*
|
|
129
|
+
* @group HAP Accessory Server
|
|
131
130
|
*/
|
|
132
131
|
var HAPHTTPCode;
|
|
133
132
|
(function (HAPHTTPCode) {
|
|
@@ -146,6 +145,8 @@ var HAPHTTPCode;
|
|
|
146
145
|
/**
|
|
147
146
|
* When in a request is made to the pairing endpoints, and mime type is 'application/pairing+tlv8'
|
|
148
147
|
* one should use the below status codes.
|
|
148
|
+
*
|
|
149
|
+
* @group HAP Accessory Server
|
|
149
150
|
*/
|
|
150
151
|
var HAPPairingHTTPCode;
|
|
151
152
|
(function (HAPPairingHTTPCode) {
|
|
@@ -157,6 +158,9 @@ var HAPPairingHTTPCode;
|
|
|
157
158
|
HAPPairingHTTPCode[HAPPairingHTTPCode["CONNECTION_AUTHORIZATION_REQUIRED"] = 470] = "CONNECTION_AUTHORIZATION_REQUIRED";
|
|
158
159
|
HAPPairingHTTPCode[HAPPairingHTTPCode["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
159
160
|
})(HAPPairingHTTPCode = exports.HAPPairingHTTPCode || (exports.HAPPairingHTTPCode = {}));
|
|
161
|
+
/**
|
|
162
|
+
* @group HAP Accessory Server
|
|
163
|
+
*/
|
|
160
164
|
var HAPServerEventTypes;
|
|
161
165
|
(function (HAPServerEventTypes) {
|
|
162
166
|
/**
|
|
@@ -171,9 +175,6 @@ var HAPServerEventTypes;
|
|
|
171
175
|
HAPServerEventTypes["ADD_PAIRING"] = "add-pairing";
|
|
172
176
|
HAPServerEventTypes["REMOVE_PAIRING"] = "remove-pairing";
|
|
173
177
|
HAPServerEventTypes["LIST_PAIRINGS"] = "list-pairings";
|
|
174
|
-
HAPServerEventTypes["GENERATE_SETUP_CODE"] = "generate-setup-code";
|
|
175
|
-
HAPServerEventTypes["PAIR_SETUP_STARTED"] = "pair-setup-started";
|
|
176
|
-
HAPServerEventTypes["PAIR_SETUP_FINISHED"] = "pair-setup-finished";
|
|
177
178
|
/**
|
|
178
179
|
* This event is emitted when a client completes the "pairing" process and exchanges encryption keys.
|
|
179
180
|
* Note that this does not mean the "Add Accessory" process in iOS has completed.
|
|
@@ -221,29 +222,28 @@ var HAPServerEventTypes;
|
|
|
221
222
|
* the connection is open, the server can elect to issue "EVENT/1.0 200 OK" HTTP-style responses. These are
|
|
222
223
|
* typically sent to inform the iOS device of a characteristic change for the accessory (like "Door was Unlocked").
|
|
223
224
|
*
|
|
224
|
-
* See
|
|
225
|
+
* See {@link EventedHTTPServer} for more detail on the implementation of this protocol.
|
|
226
|
+
*
|
|
227
|
+
* @group HAP Accessory Server
|
|
225
228
|
*/
|
|
226
229
|
var HAPServer = /** @class */ (function (_super) {
|
|
227
230
|
tslib_1.__extends(HAPServer, _super);
|
|
228
231
|
function HAPServer(accessoryInfo) {
|
|
229
232
|
var _this = _super.call(this) || this;
|
|
230
233
|
_this.unsuccessfulPairAttempts = 0; // after 100 unsuccessful attempts the server won't accept any further attempts. Will currently be reset on a reboot
|
|
231
|
-
/** Session currently trying to pair with the server */
|
|
232
|
-
_this._pairing = null;
|
|
233
|
-
_this._setupCodeIdentity = null;
|
|
234
234
|
_this.accessoryInfo = accessoryInfo;
|
|
235
235
|
_this.allowInsecureRequest = false;
|
|
236
236
|
// internal server that does all the actual communication
|
|
237
237
|
_this.httpServer = new eventedhttp_1.EventedHTTPServer();
|
|
238
|
-
_this.httpServer.on("listening" /* LISTENING */, _this.onListening.bind(_this));
|
|
239
|
-
_this.httpServer.on("request" /* REQUEST */, _this.handleRequestOnHAPConnection.bind(_this));
|
|
240
|
-
_this.httpServer.on("connection-closed" /* CONNECTION_CLOSED */, _this.handleConnectionClosed.bind(_this));
|
|
238
|
+
_this.httpServer.on("listening" /* EventedHTTPServerEvent.LISTENING */, _this.onListening.bind(_this));
|
|
239
|
+
_this.httpServer.on("request" /* EventedHTTPServerEvent.REQUEST */, _this.handleRequestOnHAPConnection.bind(_this));
|
|
240
|
+
_this.httpServer.on("connection-closed" /* EventedHTTPServerEvent.CONNECTION_CLOSED */, _this.handleConnectionClosed.bind(_this));
|
|
241
241
|
return _this;
|
|
242
242
|
}
|
|
243
243
|
HAPServer.prototype.listen = function (port, host) {
|
|
244
244
|
if (port === void 0) { port = 0; }
|
|
245
245
|
if (host === "::") {
|
|
246
|
-
// this will
|
|
246
|
+
// this will work around "EAFNOSUPPORT: address family not supported" errors
|
|
247
247
|
// on systems where IPv6 is not supported/enabled, we just use the node default then by supplying undefined
|
|
248
248
|
host = undefined;
|
|
249
249
|
}
|
|
@@ -257,15 +257,15 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
257
257
|
this.removeAllListeners();
|
|
258
258
|
};
|
|
259
259
|
/**
|
|
260
|
-
* Send
|
|
261
|
-
* If
|
|
260
|
+
* Send an even notification for given characteristic and changed value to all connected clients.
|
|
261
|
+
* If `originator` is specified, the given {@link HAPConnection} will be excluded from the broadcast.
|
|
262
262
|
*
|
|
263
263
|
* @param aid - The accessory id of the updated characteristic.
|
|
264
264
|
* @param iid - The instance id of the updated characteristic.
|
|
265
265
|
* @param value - The newly set value of the characteristic.
|
|
266
|
-
* @param originator - If specified, the connection will not get
|
|
266
|
+
* @param originator - If specified, the connection will not get an event message.
|
|
267
267
|
* @param immediateDelivery - The HAP spec requires some characteristics to be delivery immediately.
|
|
268
|
-
* Namely for the {@link ButtonEvent} and the {@link ProgrammableSwitchEvent} characteristics.
|
|
268
|
+
* Namely, for the {@link Characteristic.ButtonEvent} and the {@link Characteristic.ProgrammableSwitchEvent} characteristics.
|
|
269
269
|
*/
|
|
270
270
|
HAPServer.prototype.sendEventNotifications = function (aid, iid, value, originator, immediateDelivery) {
|
|
271
271
|
try {
|
|
@@ -276,21 +276,21 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
276
276
|
}
|
|
277
277
|
};
|
|
278
278
|
HAPServer.prototype.onListening = function (port, hostname) {
|
|
279
|
-
this.emit("listening" /* LISTENING */, port, hostname);
|
|
279
|
+
this.emit("listening" /* HAPServerEventTypes.LISTENING */, port, hostname);
|
|
280
280
|
};
|
|
281
281
|
// Called when an HTTP request was detected.
|
|
282
282
|
HAPServer.prototype.handleRequestOnHAPConnection = function (connection, request, response) {
|
|
283
283
|
var _this = this;
|
|
284
284
|
debug("[%s] HAP Request: %s %s", this.accessoryInfo.username, request.method, request.url);
|
|
285
285
|
var buffers = [];
|
|
286
|
-
request.on(
|
|
287
|
-
request.on(
|
|
286
|
+
request.on("data", function (data) { return buffers.push(data); });
|
|
287
|
+
request.on("end", function () {
|
|
288
288
|
var url = new url_1.URL(request.url, "http://hap-nodejs.local"); // parse the url (query strings etc)
|
|
289
|
-
var handler = _this.getHandler(url);
|
|
289
|
+
var handler = _this.getHandler(url);
|
|
290
290
|
if (!handler) {
|
|
291
291
|
debug("[%s] WARNING: Handler for %s not implemented", _this.accessoryInfo.username, request.url);
|
|
292
|
-
response.writeHead(404 /* NOT_FOUND */, {
|
|
293
|
-
response.end(JSON.stringify({ status: -70409 /* RESOURCE_DOES_NOT_EXIST */ }));
|
|
292
|
+
response.writeHead(404 /* HAPHTTPCode.NOT_FOUND */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
293
|
+
response.end(JSON.stringify({ status: -70409 /* HAPStatus.RESOURCE_DOES_NOT_EXIST */ }));
|
|
294
294
|
}
|
|
295
295
|
else {
|
|
296
296
|
var data = Buffer.concat(buffers);
|
|
@@ -299,14 +299,14 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
299
299
|
}
|
|
300
300
|
catch (error) {
|
|
301
301
|
debug("[%s] Error executing route handler: %s", _this.accessoryInfo.username, error.stack);
|
|
302
|
-
response.writeHead(500 /* INTERNAL_SERVER_ERROR */, {
|
|
303
|
-
response.end(JSON.stringify({ status: -70403 /* RESOURCE_BUSY */ })); // resource busy try again, does somehow fit?
|
|
302
|
+
response.writeHead(500 /* HAPHTTPCode.INTERNAL_SERVER_ERROR */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
303
|
+
response.end(JSON.stringify({ status: -70403 /* HAPStatus.RESOURCE_BUSY */ })); // resource busy try again, does somehow fit?
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
});
|
|
307
307
|
};
|
|
308
308
|
HAPServer.prototype.handleConnectionClosed = function (connection) {
|
|
309
|
-
this.emit("connection-closed" /* CONNECTION_CLOSED */, connection);
|
|
309
|
+
this.emit("connection-closed" /* HAPServerEventTypes.CONNECTION_CLOSED */, connection);
|
|
310
310
|
};
|
|
311
311
|
HAPServer.prototype.getHandler = function (url) {
|
|
312
312
|
switch (url.pathname.toLowerCase()) {
|
|
@@ -336,186 +336,80 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
336
336
|
HAPServer.prototype.handleIdentifyRequest = function (connection, url, request, data, response) {
|
|
337
337
|
var _this = this;
|
|
338
338
|
// POST body is empty
|
|
339
|
-
if (
|
|
340
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" });
|
|
341
|
-
response.end(JSON.stringify({ status: -70401 /* INSUFFICIENT_PRIVILEGES */ }));
|
|
339
|
+
if (this.accessoryInfo.paired() && !this.allowInsecureRequest) {
|
|
340
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
341
|
+
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
|
-
this.emit("identify" /* IDENTIFY */, once_1.once(function (err) {
|
|
344
|
+
this.emit("identify" /* HAPServerEventTypes.IDENTIFY */, (0, once_1.once)(function (err) {
|
|
345
345
|
if (!err) {
|
|
346
346
|
debug("[%s] Identification success", _this.accessoryInfo.username);
|
|
347
|
-
response.writeHead(204 /* NO_CONTENT */);
|
|
347
|
+
response.writeHead(204 /* HAPHTTPCode.NO_CONTENT */);
|
|
348
348
|
response.end();
|
|
349
349
|
}
|
|
350
350
|
else {
|
|
351
351
|
debug("[%s] Identification error: %s", _this.accessoryInfo.username, err.message);
|
|
352
|
-
response.writeHead(500 /* INTERNAL_SERVER_ERROR */, { "Content-Type": "application/hap+json" });
|
|
353
|
-
response.end(JSON.stringify({ status: -70403 /* RESOURCE_BUSY */ }));
|
|
352
|
+
response.writeHead(500 /* HAPHTTPCode.INTERNAL_SERVER_ERROR */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
353
|
+
response.end(JSON.stringify({ status: -70403 /* HAPStatus.RESOURCE_BUSY */ }));
|
|
354
354
|
}
|
|
355
355
|
}));
|
|
356
356
|
};
|
|
357
357
|
HAPServer.prototype.handlePairSetup = function (connection, url, request, data, response) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
return [4 /*yield*/, this.handlePairSetupM1(connection, request, response, tlvData)];
|
|
388
|
-
case 2:
|
|
389
|
-
_a.sent();
|
|
390
|
-
return [3 /*break*/, 4];
|
|
391
|
-
case 3:
|
|
392
|
-
if (sequence == 3 /* M3 */ && connection._pairSetupState === 2 /* M2 */) {
|
|
393
|
-
this.handlePairSetupM3(connection, request, response, tlvData);
|
|
394
|
-
}
|
|
395
|
-
else if (sequence == 5 /* M5 */ && connection._pairSetupState === 4 /* M4 */) {
|
|
396
|
-
this.handlePairSetupM5(connection, request, response, tlvData);
|
|
397
|
-
}
|
|
398
|
-
else
|
|
399
|
-
throw new Error('Invalid state/sequence number');
|
|
400
|
-
_a.label = 4;
|
|
401
|
-
case 4: return [3 /*break*/, 6];
|
|
402
|
-
case 5:
|
|
403
|
-
error_1 = _a.sent();
|
|
404
|
-
debug("[%s] Error occurred during pairing: %s", this.accessoryInfo.username, error_1.message);
|
|
405
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/pairing+tlv8" });
|
|
406
|
-
response.end(tlv.encode(6 /* STATE */, sequence + 1, 7 /* ERROR_CODE */, 1 /* UNKNOWN */));
|
|
407
|
-
this._pairing = null;
|
|
408
|
-
return [3 /*break*/, 6];
|
|
409
|
-
case 6: return [2 /*return*/];
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
};
|
|
414
|
-
HAPServer.prototype.handlePairSetupM1 = function (connection, request, response, tlvData) {
|
|
415
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
416
|
-
var flags, decodedFlags, transient, split, setupcode, salt_1, verifier, err_1, setupcode, salt_2, verifier, salt, key, srpServer, srpB, responseTLV;
|
|
417
|
-
return tslib_1.__generator(this, function (_a) {
|
|
418
|
-
switch (_a.label) {
|
|
419
|
-
case 0:
|
|
420
|
-
debug("[%s] Pair step 1/5", this.accessoryInfo.username);
|
|
421
|
-
if (tlvData[0 /* METHOD */][0] !== 0 /* PAIR_SETUP */) {
|
|
422
|
-
response.writeHead(200, { "Content-Type": "application/pairing+tlv8" });
|
|
423
|
-
response.end(tlv.encode(6 /* STATE */, 2 /* M2 */, 7 /* ERROR_CODE */, 6 /* UNAVAILABLE */));
|
|
424
|
-
return [2 /*return*/];
|
|
425
|
-
}
|
|
426
|
-
flags = tlvData[19 /* FLAGS */];
|
|
427
|
-
decodedFlags = flags && flags.length === 4 ? tlv.readUInt32(flags) : null;
|
|
428
|
-
transient = !!decodedFlags && !!(decodedFlags & PairingFlags.TRANSIENT);
|
|
429
|
-
split = !!decodedFlags && !!(decodedFlags & PairingFlags.SPLIT);
|
|
430
|
-
connection._pairSetupFlags = {
|
|
431
|
-
raw: flags, flags: decodedFlags,
|
|
432
|
-
transient: transient, split: split,
|
|
433
|
-
};
|
|
434
|
-
if (!((!decodedFlags || (transient && split)) && this.listenerCount("generate-setup-code" /* GENERATE_SETUP_CODE */))) return [3 /*break*/, 5];
|
|
435
|
-
_a.label = 1;
|
|
436
|
-
case 1:
|
|
437
|
-
_a.trys.push([1, 3, , 4]);
|
|
438
|
-
return [4 /*yield*/, this._getSetupCodeForPairing(connection)];
|
|
439
|
-
case 2:
|
|
440
|
-
setupcode = _a.sent();
|
|
441
|
-
salt_1 = crypto_1.default.randomBytes(16);
|
|
442
|
-
verifier = fast_srp_hap_1.SRP.computeVerifier(fast_srp_hap_1.SRP.params.hap, salt_1, Buffer.from('Pair-Setup'), Buffer.from(setupcode));
|
|
443
|
-
this._setupCodeIdentity = { username: 'Pair-Setup', salt: salt_1, verifier: verifier, setupcode: setupcode };
|
|
444
|
-
debug('[%s] Starting standard pairing with generated setup code: %s', this.accessoryInfo.username, setupcode);
|
|
445
|
-
return [3 /*break*/, 4];
|
|
446
|
-
case 3:
|
|
447
|
-
err_1 = _a.sent();
|
|
448
|
-
debug("[%s] Error occurred when generating setup code: %s", this.accessoryInfo.username, err_1.message);
|
|
449
|
-
response.writeHead(200, { "Content-Type": "application/pairing+tlv8" });
|
|
450
|
-
response.end(tlv.encode(6 /* STATE */, 2 /* M2 */, 7 /* ERROR_CODE */, 6 /* UNAVAILABLE */));
|
|
451
|
-
this._pairing = null;
|
|
452
|
-
return [2 /*return*/];
|
|
453
|
-
case 4: return [3 /*break*/, 6];
|
|
454
|
-
case 5:
|
|
455
|
-
if (split && this._setupCodeIdentity) {
|
|
456
|
-
// Nothing to do here
|
|
457
|
-
debug('[%s] Starting split pairing', this.accessoryInfo.username);
|
|
458
|
-
}
|
|
459
|
-
else if (typeof this.accessoryInfo.pincode === 'object' && this.accessoryInfo.pincode) {
|
|
460
|
-
this._setupCodeIdentity = tslib_1.__assign(tslib_1.__assign({}, this.accessoryInfo.pincode), { username: 'Pair-Setup', setupcode: null });
|
|
461
|
-
debug('[%s] Starting standard pairing with saved verifier', this.accessoryInfo.username);
|
|
462
|
-
}
|
|
463
|
-
else if (typeof this.accessoryInfo.pincode === 'string') {
|
|
464
|
-
setupcode = this.accessoryInfo.pincode;
|
|
465
|
-
salt_2 = crypto_1.default.randomBytes(16);
|
|
466
|
-
verifier = fast_srp_hap_1.SRP.computeVerifier(fast_srp_hap_1.SRP.params.hap, salt_2, Buffer.from('Pair-Setup'), Buffer.from(setupcode));
|
|
467
|
-
this._setupCodeIdentity = { username: 'Pair-Setup', salt: salt_2, verifier: verifier, setupcode: setupcode };
|
|
468
|
-
debug('[%s] Starting standard pairing with fixed setup code: %s', this.accessoryInfo.username, setupcode);
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
if (!decodedFlags || (transient && split)) {
|
|
472
|
-
debug('[%s] No setup code configured', this.accessoryInfo.username);
|
|
473
|
-
}
|
|
474
|
-
response.writeHead(200, { "Content-Type": "application/pairing+tlv8" });
|
|
475
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 2 /* M2 */, 7 /* ERROR_CODE */, 2 /* AUTHENTICATION */));
|
|
476
|
-
this._pairing = null;
|
|
477
|
-
return [2 /*return*/];
|
|
478
|
-
}
|
|
479
|
-
_a.label = 6;
|
|
480
|
-
case 6:
|
|
481
|
-
salt = this._setupCodeIdentity.salt;
|
|
482
|
-
return [4 /*yield*/, fast_srp_hap_1.SRP.genKey(32)];
|
|
483
|
-
case 7:
|
|
484
|
-
key = _a.sent();
|
|
485
|
-
srpServer = new fast_srp_hap_1.SrpServer(fast_srp_hap_1.SRP.params.hap, this._setupCodeIdentity, key);
|
|
486
|
-
srpB = srpServer.computeB();
|
|
487
|
-
// attach it to the current TCP session
|
|
488
|
-
connection.srpServer = srpServer;
|
|
489
|
-
responseTLV = tlv.encode(6 /* SEQUENCE_NUM */, 2 /* M2 */, 2 /* SALT */, salt, 3 /* PUBLIC_KEY */, srpB);
|
|
490
|
-
response.writeHead(200, { "Content-Type": "application/pairing+tlv8" });
|
|
491
|
-
response.end(flags ? Buffer.concat([responseTLV, tlv.encode(19 /* FLAGS */, flags)]) : responseTLV);
|
|
492
|
-
connection._pairSetupState = 2 /* M2 */;
|
|
493
|
-
this.emit("pair-setup-started" /* PAIR_SETUP_STARTED */, this._setupCodeIdentity, connection);
|
|
494
|
-
return [2 /*return*/];
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
});
|
|
358
|
+
// Can only be directly paired with one iOS device
|
|
359
|
+
if (!this.allowInsecureRequest && this.accessoryInfo.paired()) {
|
|
360
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
361
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, 6 /* TLVErrorCode.UNAVAILABLE */));
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (this.unsuccessfulPairAttempts > 100) {
|
|
365
|
+
debug("[%s] Reached maximum amount of unsuccessful pair attempts!", this.accessoryInfo.username);
|
|
366
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
367
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, 5 /* TLVErrorCode.MAX_TRIES */));
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
var tlvData = tlv.decode(data);
|
|
371
|
+
var sequence = tlvData[6 /* TLVValues.SEQUENCE_NUM */][0]; // value is single byte with sequence number
|
|
372
|
+
if (sequence === 1 /* PairingStates.M1 */) {
|
|
373
|
+
this.handlePairSetupM1(connection, request, response);
|
|
374
|
+
}
|
|
375
|
+
else if (sequence === 3 /* PairingStates.M3 */ && connection._pairSetupState === 2 /* PairingStates.M2 */) {
|
|
376
|
+
this.handlePairSetupM3(connection, request, response, tlvData);
|
|
377
|
+
}
|
|
378
|
+
else if (sequence === 5 /* PairingStates.M5 */ && connection._pairSetupState === 4 /* PairingStates.M4 */) {
|
|
379
|
+
this.handlePairSetupM5(connection, request, response, tlvData);
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
// Invalid state/sequence number
|
|
383
|
+
response.writeHead(400 /* HAPPairingHTTPCode.BAD_REQUEST */, { "Content-Type": "application/pairing+tlv8" });
|
|
384
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, sequence + 1, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
498
387
|
};
|
|
499
|
-
HAPServer.prototype.
|
|
388
|
+
HAPServer.prototype.handlePairSetupM1 = function (connection, request, response) {
|
|
500
389
|
var _this = this;
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
390
|
+
debug("[%s] Pair step 1/5", this.accessoryInfo.username);
|
|
391
|
+
var salt = crypto_1.default.randomBytes(16);
|
|
392
|
+
var srpParams = fast_srp_hap_1.SRP.params.hap;
|
|
393
|
+
fast_srp_hap_1.SRP.genKey(32).then(function (key) {
|
|
394
|
+
// create a new SRP server
|
|
395
|
+
var srpServer = new fast_srp_hap_1.SrpServer(srpParams, salt, Buffer.from("Pair-Setup"), Buffer.from(_this.accessoryInfo.pincode), key);
|
|
396
|
+
var srpB = srpServer.computeB();
|
|
397
|
+
// attach it to the current TCP session
|
|
398
|
+
connection.srpServer = srpServer;
|
|
399
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
400
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 2 /* PairingStates.M2 */, 2 /* TLVValues.SALT */, salt, 3 /* TLVValues.PUBLIC_KEY */, srpB));
|
|
401
|
+
connection._pairSetupState = 2 /* PairingStates.M2 */;
|
|
402
|
+
}).catch(function (error) {
|
|
403
|
+
debug("[%s] Error occurred when generating srp key: %s", _this.accessoryInfo.username, error.message);
|
|
404
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
405
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
406
|
+
return;
|
|
513
407
|
});
|
|
514
408
|
};
|
|
515
409
|
HAPServer.prototype.handlePairSetupM3 = function (connection, request, response, tlvData) {
|
|
516
410
|
debug("[%s] Pair step 2/5", this.accessoryInfo.username);
|
|
517
|
-
var A = tlvData[3 /* PUBLIC_KEY */]; // "A is a public key that exists only for a single login session."
|
|
518
|
-
var M1 = tlvData[4 /* PASSWORD_PROOF */]; // "M1 is the proof that you actually know your own password."
|
|
411
|
+
var A = tlvData[3 /* TLVValues.PUBLIC_KEY */]; // "A is a public key that exists only for a single login session."
|
|
412
|
+
var M1 = tlvData[4 /* TLVValues.PASSWORD_PROOF */]; // "M1 is the proof that you actually know your own password."
|
|
519
413
|
// pull the SRP server we created in stepOne out of the current session
|
|
520
414
|
var srpServer = connection.srpServer;
|
|
521
415
|
srpServer.setA(A);
|
|
@@ -526,34 +420,22 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
526
420
|
// most likely the client supplied an incorrect pincode.
|
|
527
421
|
this.unsuccessfulPairAttempts++;
|
|
528
422
|
debug("[%s] Error while checking pincode: %s", this.accessoryInfo.username, err.message);
|
|
529
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
530
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 4 /* M4 */, 7 /* ERROR_CODE */, 2 /* AUTHENTICATION */));
|
|
531
|
-
|
|
423
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
424
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 4 /* PairingStates.M4 */, 7 /* TLVValues.ERROR_CODE */, 2 /* TLVErrorCode.AUTHENTICATION */));
|
|
425
|
+
connection._pairSetupState = undefined;
|
|
532
426
|
return;
|
|
533
427
|
}
|
|
534
428
|
// "M2 is the proof that the server actually knows your password."
|
|
535
429
|
var M2 = srpServer.computeM2();
|
|
536
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
537
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 4 /* M4 */, 4 /* PASSWORD_PROOF */, M2));
|
|
538
|
-
connection._pairSetupState = 4 /* M4 */;
|
|
539
|
-
if (connection._pairSetupFlags.transient) {
|
|
540
|
-
this._handlePairFinished(null, null, connection);
|
|
541
|
-
// For transient pair setup we should enable session encryption now
|
|
542
|
-
var sharedSec = srpServer.computeK();
|
|
543
|
-
var enc = connection.encryption = new eventedhttp_1.HAPEncryption(Buffer.alloc(0), Buffer.alloc(0), Buffer.alloc(0), sharedSec, Buffer.alloc(0));
|
|
544
|
-
var encSalt = Buffer.from("SplitSetupSalt");
|
|
545
|
-
var infoRead = Buffer.from("ControllerEncrypt-Control");
|
|
546
|
-
var infoWrite = Buffer.from("AccessoryEncrypt-Control");
|
|
547
|
-
enc.controllerToAccessoryKey = hapCrypto.HKDF("sha512", encSalt, sharedSec, infoRead, 32);
|
|
548
|
-
enc.accessoryToControllerKey = hapCrypto.HKDF("sha512", encSalt, sharedSec, infoWrite, 32);
|
|
549
|
-
// TODO: how should the session be authenticated? We don't have any identification here.
|
|
550
|
-
}
|
|
430
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
431
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 4 /* PairingStates.M4 */, 4 /* TLVValues.PASSWORD_PROOF */, M2));
|
|
432
|
+
connection._pairSetupState = 4 /* PairingStates.M4 */;
|
|
551
433
|
};
|
|
552
434
|
HAPServer.prototype.handlePairSetupM5 = function (connection, request, response, tlvData) {
|
|
553
435
|
debug("[%s] Pair step 3/5", this.accessoryInfo.username);
|
|
554
436
|
// pull the SRP server we created in stepOne out of the current session
|
|
555
437
|
var srpServer = connection.srpServer;
|
|
556
|
-
var encryptedData = tlvData[5 /* ENCRYPTED_DATA */];
|
|
438
|
+
var encryptedData = tlvData[5 /* TLVValues.ENCRYPTED_DATA */];
|
|
557
439
|
var messageData = Buffer.alloc(encryptedData.length - 16);
|
|
558
440
|
var authTagData = Buffer.alloc(16);
|
|
559
441
|
encryptedData.copy(messageData, 0, 0, encryptedData.length - 16);
|
|
@@ -568,16 +450,16 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
568
450
|
}
|
|
569
451
|
catch (error) {
|
|
570
452
|
debug("[%s] Error while decrypting and verifying M5 subTlv: %s", this.accessoryInfo.username);
|
|
571
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
572
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */,
|
|
573
|
-
|
|
453
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
454
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 4 /* PairingStates.M4 */, 7 /* TLVValues.ERROR_CODE */, 2 /* TLVErrorCode.AUTHENTICATION */));
|
|
455
|
+
connection._pairSetupState = undefined;
|
|
574
456
|
return;
|
|
575
457
|
}
|
|
576
458
|
// decode the client payload and pass it on to the next step
|
|
577
459
|
var M5Packet = tlv.decode(plaintext);
|
|
578
|
-
var clientUsername = M5Packet[1 /* USERNAME */];
|
|
579
|
-
var clientLTPK = M5Packet[3 /* PUBLIC_KEY */];
|
|
580
|
-
var clientProof = M5Packet[10 /* PROOF */];
|
|
460
|
+
var clientUsername = M5Packet[1 /* TLVValues.USERNAME */];
|
|
461
|
+
var clientLTPK = M5Packet[3 /* TLVValues.PUBLIC_KEY */];
|
|
462
|
+
var clientProof = M5Packet[10 /* TLVValues.PROOF */];
|
|
581
463
|
this.handlePairSetupM5_2(connection, request, response, clientUsername, clientLTPK, clientProof, outputKey);
|
|
582
464
|
};
|
|
583
465
|
// M5-2
|
|
@@ -590,9 +472,9 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
590
472
|
var completeData = Buffer.concat([outputKey, clientUsername, clientLTPK]);
|
|
591
473
|
if (!tweetnacl_1.default.sign.detached.verify(completeData, clientProof, clientLTPK)) {
|
|
592
474
|
debug("[%s] Invalid signature", this.accessoryInfo.username);
|
|
593
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
594
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 6 /* M6 */, 7 /* ERROR_CODE */, 2 /* AUTHENTICATION */));
|
|
595
|
-
|
|
475
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
476
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 6 /* PairingStates.M6 */, 7 /* TLVValues.ERROR_CODE */, 2 /* TLVErrorCode.AUTHENTICATION */));
|
|
477
|
+
connection._pairSetupState = undefined;
|
|
596
478
|
return;
|
|
597
479
|
}
|
|
598
480
|
this.handlePairSetupM5_3(connection, request, response, clientUsername, clientLTPK, hkdfEncKey);
|
|
@@ -610,47 +492,42 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
610
492
|
var material = Buffer.concat([outputKey, usernameData, serverLTPK]);
|
|
611
493
|
var privateKey = Buffer.from(this.accessoryInfo.signSk);
|
|
612
494
|
var serverProof = tweetnacl_1.default.sign.detached(material, privateKey);
|
|
613
|
-
var message = tlv.encode(1 /* USERNAME */, usernameData, 3 /* PUBLIC_KEY */, serverLTPK, 10 /* PROOF */, serverProof);
|
|
495
|
+
var message = tlv.encode(1 /* TLVValues.USERNAME */, usernameData, 3 /* TLVValues.PUBLIC_KEY */, serverLTPK, 10 /* TLVValues.PROOF */, serverProof);
|
|
614
496
|
var encrypted = hapCrypto.chacha20_poly1305_encryptAndSeal(hkdfEncKey, Buffer.from("PS-Msg06"), null, message);
|
|
615
497
|
// finally, notify listeners that we have been paired with a client
|
|
616
|
-
this.emit("pair" /* PAIR */, clientUsername.toString(), clientLTPK, once_1.once(function (err) {
|
|
498
|
+
this.emit("pair" /* HAPServerEventTypes.PAIR */, clientUsername.toString(), clientLTPK, (0, once_1.once)(function (err) {
|
|
617
499
|
if (err) {
|
|
618
500
|
debug("[%s] Error adding pairing info: %s", _this.accessoryInfo.username, err.message);
|
|
619
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
620
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 6 /* M6 */, 7 /* ERROR_CODE */, 1 /* UNKNOWN */));
|
|
621
|
-
|
|
501
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
502
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 6 /* PairingStates.M6 */, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
503
|
+
connection._pairSetupState = undefined;
|
|
622
504
|
return;
|
|
623
505
|
}
|
|
624
506
|
// send final pairing response to client
|
|
625
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
626
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 6 /* M6 */, 5 /* ENCRYPTED_DATA */, Buffer.concat([encrypted.ciphertext, encrypted.authTag])));
|
|
627
|
-
|
|
507
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
508
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 6 /* PairingStates.M6 */, 5 /* TLVValues.ENCRYPTED_DATA */, Buffer.concat([encrypted.ciphertext, encrypted.authTag])));
|
|
509
|
+
connection._pairSetupState = undefined;
|
|
628
510
|
}));
|
|
629
511
|
};
|
|
630
|
-
// It's possible for both err and clientUsername to be null (transient pair setup)
|
|
631
|
-
HAPServer.prototype._handlePairFinished = function (err, clientUsername, connection) {
|
|
632
|
-
this._pairing = null;
|
|
633
|
-
connection._pairSetupState = undefined;
|
|
634
|
-
connection._pairSetupFlags = undefined;
|
|
635
|
-
this.emit("pair-setup-finished" /* PAIR_SETUP_FINISHED */, err && err instanceof Array ? new Error("" + err[1]) : err, clientUsername, connection);
|
|
636
|
-
};
|
|
637
512
|
HAPServer.prototype.handlePairVerify = function (connection, url, request, data, response) {
|
|
638
513
|
var tlvData = tlv.decode(data);
|
|
639
|
-
var sequence = tlvData[6 /* SEQUENCE_NUM */][0]; // value is single byte with sequence number
|
|
640
|
-
if (sequence
|
|
514
|
+
var sequence = tlvData[6 /* TLVValues.SEQUENCE_NUM */][0]; // value is single byte with sequence number
|
|
515
|
+
if (sequence === 1 /* PairingStates.M1 */) {
|
|
641
516
|
this.handlePairVerifyM1(connection, request, response, tlvData);
|
|
642
|
-
|
|
643
|
-
|
|
517
|
+
}
|
|
518
|
+
else if (sequence === 3 /* PairingStates.M3 */ && connection._pairVerifyState === 2 /* PairingStates.M2 */) {
|
|
519
|
+
this.handlePairVerifyM3(connection, request, response, tlvData);
|
|
520
|
+
}
|
|
644
521
|
else {
|
|
645
522
|
// Invalid state/sequence number
|
|
646
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/pairing+tlv8" });
|
|
647
|
-
response.end(tlv.encode(6 /* STATE */, sequence + 1, 7 /* ERROR_CODE */, 1 /* UNKNOWN */));
|
|
523
|
+
response.writeHead(400 /* HAPPairingHTTPCode.BAD_REQUEST */, { "Content-Type": "application/pairing+tlv8" });
|
|
524
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, sequence + 1, 7 /* TLVValues.ERROR_CODE */, 1 /* TLVErrorCode.UNKNOWN */));
|
|
648
525
|
return;
|
|
649
526
|
}
|
|
650
527
|
};
|
|
651
528
|
HAPServer.prototype.handlePairVerifyM1 = function (connection, request, response, tlvData) {
|
|
652
529
|
debug("[%s] Pair verify step 1/2", this.accessoryInfo.username);
|
|
653
|
-
var clientPublicKey = tlvData[3 /* PUBLIC_KEY */]; // Buffer
|
|
530
|
+
var clientPublicKey = tlvData[3 /* TLVValues.PUBLIC_KEY */]; // Buffer
|
|
654
531
|
// generate new encryption keys for this session
|
|
655
532
|
var keyPair = hapCrypto.generateCurve25519KeyPair();
|
|
656
533
|
var secretKey = Buffer.from(keyPair.secretKey);
|
|
@@ -665,15 +542,15 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
665
542
|
var outputKey = hapCrypto.HKDF("sha512", encSalt, sharedSec, encInfo, 32).slice(0, 32);
|
|
666
543
|
connection.encryption = new eventedhttp_1.HAPEncryption(clientPublicKey, secretKey, publicKey, sharedSec, outputKey);
|
|
667
544
|
// compose the response data in TLV format
|
|
668
|
-
var message = tlv.encode(1 /* USERNAME */, usernameData, 10 /* PROOF */, serverProof);
|
|
545
|
+
var message = tlv.encode(1 /* TLVValues.USERNAME */, usernameData, 10 /* TLVValues.PROOF */, serverProof);
|
|
669
546
|
var encrypted = hapCrypto.chacha20_poly1305_encryptAndSeal(outputKey, Buffer.from("PV-Msg02"), null, message);
|
|
670
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
671
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 2 /* M2 */, 5 /* ENCRYPTED_DATA */, Buffer.concat([encrypted.ciphertext, encrypted.authTag]), 3 /* PUBLIC_KEY */, publicKey));
|
|
672
|
-
connection._pairVerifyState = 2 /* M2 */;
|
|
547
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
548
|
+
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
|
+
connection._pairVerifyState = 2 /* PairingStates.M2 */;
|
|
673
550
|
};
|
|
674
|
-
HAPServer.prototype.
|
|
551
|
+
HAPServer.prototype.handlePairVerifyM3 = function (connection, request, response, objects) {
|
|
675
552
|
debug("[%s] Pair verify step 2/2", this.accessoryInfo.username);
|
|
676
|
-
var encryptedData = objects[5 /* ENCRYPTED_DATA */];
|
|
553
|
+
var encryptedData = objects[5 /* TLVValues.ENCRYPTED_DATA */];
|
|
677
554
|
var messageData = Buffer.alloc(encryptedData.length - 16);
|
|
678
555
|
var authTagData = Buffer.alloc(16);
|
|
679
556
|
encryptedData.copy(messageData, 0, 0, encryptedData.length - 16);
|
|
@@ -686,36 +563,36 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
686
563
|
}
|
|
687
564
|
catch (error) {
|
|
688
565
|
debug("[%s] M3: Failed to decrypt and/or verify", this.accessoryInfo.username);
|
|
689
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
690
|
-
response.end(tlv.encode(6 /* STATE */, 4 /* M4 */, 7 /* ERROR_CODE */, 2 /* AUTHENTICATION */));
|
|
566
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
567
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 4 /* PairingStates.M4 */, 7 /* TLVValues.ERROR_CODE */, 2 /* TLVErrorCode.AUTHENTICATION */));
|
|
691
568
|
connection._pairVerifyState = undefined;
|
|
692
569
|
return;
|
|
693
570
|
}
|
|
694
571
|
var decoded = tlv.decode(plaintext);
|
|
695
|
-
var clientUsername = decoded[1 /* USERNAME */];
|
|
696
|
-
var proof = decoded[10 /* PROOF */];
|
|
572
|
+
var clientUsername = decoded[1 /* TLVValues.USERNAME */];
|
|
573
|
+
var proof = decoded[10 /* TLVValues.PROOF */];
|
|
697
574
|
var material = Buffer.concat([enc.clientPublicKey, clientUsername, enc.publicKey]);
|
|
698
575
|
// since we're paired, we should have the public key stored for this client
|
|
699
576
|
var clientPublicKey = this.accessoryInfo.getClientPublicKey(clientUsername.toString());
|
|
700
|
-
// if we're not actually paired, then there's nothing to verify - this client thinks it's paired with us but we
|
|
577
|
+
// if we're not actually paired, then there's nothing to verify - this client thinks it's paired with us, but we
|
|
701
578
|
// disagree. Respond with invalid request (seems to match HomeKit Accessory Simulator behavior)
|
|
702
579
|
if (!clientPublicKey) {
|
|
703
580
|
debug("[%s] Client %s attempting to verify, but we are not paired; rejecting client", this.accessoryInfo.username, clientUsername);
|
|
704
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
705
|
-
response.end(tlv.encode(6 /* STATE */, 4 /* M4 */, 7 /* ERROR_CODE */, 2 /* AUTHENTICATION */));
|
|
581
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
582
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 4 /* PairingStates.M4 */, 7 /* TLVValues.ERROR_CODE */, 2 /* TLVErrorCode.AUTHENTICATION */));
|
|
706
583
|
connection._pairVerifyState = undefined;
|
|
707
584
|
return;
|
|
708
585
|
}
|
|
709
586
|
if (!tweetnacl_1.default.sign.detached.verify(material, proof, clientPublicKey)) {
|
|
710
587
|
debug("[%s] Client %s provided an invalid signature", this.accessoryInfo.username, clientUsername);
|
|
711
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
712
|
-
response.end(tlv.encode(6 /* STATE */, 4 /* M4 */, 7 /* ERROR_CODE */, 2 /* AUTHENTICATION */));
|
|
588
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
589
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 4 /* PairingStates.M4 */, 7 /* TLVValues.ERROR_CODE */, 2 /* TLVErrorCode.AUTHENTICATION */));
|
|
713
590
|
connection._pairVerifyState = undefined;
|
|
714
591
|
return;
|
|
715
592
|
}
|
|
716
593
|
debug("[%s] Client %s verification complete", this.accessoryInfo.username, clientUsername);
|
|
717
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
718
|
-
response.end(tlv.encode(6 /* SEQUENCE_NUM */, 4 /* M4 */));
|
|
594
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
595
|
+
response.end(tlv.encode(6 /* TLVValues.SEQUENCE_NUM */, 4 /* PairingStates.M4 */));
|
|
719
596
|
// now that the client has been verified, we must "upgrade" our pseudo-HTTP connection to include
|
|
720
597
|
// TCP-level encryption. We'll do this by adding some more encryption vars to the session, and using them
|
|
721
598
|
// in future calls to onEncrypt, onDecrypt.
|
|
@@ -732,63 +609,64 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
732
609
|
var _this = this;
|
|
733
610
|
// Only accept /pairing request if there is a secure session
|
|
734
611
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
735
|
-
response.writeHead(470 /* CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" });
|
|
736
|
-
response.end(JSON.stringify({ status: -70401 /* INSUFFICIENT_PRIVILEGES */ }));
|
|
612
|
+
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
613
|
+
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
737
614
|
return;
|
|
738
615
|
}
|
|
739
616
|
var objects = tlv.decode(data);
|
|
740
|
-
var method = objects[0 /* METHOD */][0]; // value is single byte with request type
|
|
741
|
-
var state = objects[6 /* STATE */][0];
|
|
742
|
-
if (state !== 1 /* M1 */) {
|
|
617
|
+
var method = objects[0 /* TLVValues.METHOD */][0]; // value is single byte with request type
|
|
618
|
+
var state = objects[6 /* TLVValues.STATE */][0];
|
|
619
|
+
if (state !== 1 /* PairingStates.M1 */) {
|
|
743
620
|
return;
|
|
744
621
|
}
|
|
745
|
-
if (method === 3 /* ADD_PAIRING */) {
|
|
746
|
-
var identifier = objects[1 /* IDENTIFIER */].toString();
|
|
747
|
-
var publicKey = objects[3 /* PUBLIC_KEY */];
|
|
748
|
-
var permissions = objects[11 /* PERMISSIONS */][0];
|
|
749
|
-
this.emit("add-pairing" /* ADD_PAIRING */, connection, identifier, publicKey, permissions, once_1.once(function (error) {
|
|
622
|
+
if (method === 3 /* PairMethods.ADD_PAIRING */) {
|
|
623
|
+
var identifier = objects[1 /* TLVValues.IDENTIFIER */].toString();
|
|
624
|
+
var publicKey = objects[3 /* TLVValues.PUBLIC_KEY */];
|
|
625
|
+
var permissions = objects[11 /* TLVValues.PERMISSIONS */][0];
|
|
626
|
+
this.emit("add-pairing" /* HAPServerEventTypes.ADD_PAIRING */, connection, identifier, publicKey, permissions, (0, once_1.once)(function (error) {
|
|
750
627
|
if (error > 0) {
|
|
751
628
|
debug("[%s] Pairings: failed ADD_PAIRING with code %d", _this.accessoryInfo.username, error);
|
|
752
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
753
|
-
response.end(tlv.encode(6 /* STATE */, 2 /* M2 */, 7 /* ERROR_CODE */, error));
|
|
629
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
630
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, error));
|
|
754
631
|
return;
|
|
755
632
|
}
|
|
756
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
757
|
-
response.end(tlv.encode(6 /* STATE */, 2 /* M2 */));
|
|
633
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
634
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */));
|
|
758
635
|
debug("[%s] Pairings: successfully executed ADD_PAIRING", _this.accessoryInfo.username);
|
|
759
636
|
}));
|
|
760
637
|
}
|
|
761
|
-
else if (method === 4 /* REMOVE_PAIRING */) {
|
|
762
|
-
var identifier = objects[1 /* IDENTIFIER */].toString();
|
|
763
|
-
this.emit("remove-pairing" /* REMOVE_PAIRING */, connection, identifier, once_1.once(function (error) {
|
|
638
|
+
else if (method === 4 /* PairMethods.REMOVE_PAIRING */) {
|
|
639
|
+
var identifier = objects[1 /* TLVValues.IDENTIFIER */].toString();
|
|
640
|
+
this.emit("remove-pairing" /* HAPServerEventTypes.REMOVE_PAIRING */, connection, identifier, (0, once_1.once)(function (error) {
|
|
764
641
|
if (error > 0) {
|
|
765
642
|
debug("[%s] Pairings: failed REMOVE_PAIRING with code %d", _this.accessoryInfo.username, error);
|
|
766
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
767
|
-
response.end(tlv.encode(6 /* STATE */, 2 /* M2 */, 7 /* ERROR_CODE */, error));
|
|
643
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
644
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, error));
|
|
768
645
|
return;
|
|
769
646
|
}
|
|
770
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
771
|
-
response.end(tlv.encode(6 /* STATE */, 2 /* M2 */));
|
|
647
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
648
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */));
|
|
772
649
|
debug("[%s] Pairings: successfully executed REMOVE_PAIRING", _this.accessoryInfo.username);
|
|
773
650
|
}));
|
|
774
651
|
}
|
|
775
|
-
else if (method === 5 /* LIST_PAIRINGS */) {
|
|
776
|
-
this.emit("list-pairings" /* LIST_PAIRINGS */, connection, once_1.once(function (error, data) {
|
|
652
|
+
else if (method === 5 /* PairMethods.LIST_PAIRINGS */) {
|
|
653
|
+
this.emit("list-pairings" /* HAPServerEventTypes.LIST_PAIRINGS */, connection, (0, once_1.once)(function (error, data) {
|
|
777
654
|
if (error > 0) {
|
|
778
655
|
debug("[%s] Pairings: failed LIST_PAIRINGS with code %d", _this.accessoryInfo.username, error);
|
|
779
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
780
|
-
response.end(tlv.encode(6 /* STATE */, 2 /* M2 */, 7 /* ERROR_CODE */, error));
|
|
656
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
657
|
+
response.end(tlv.encode(6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */, 7 /* TLVValues.ERROR_CODE */, error));
|
|
781
658
|
return;
|
|
782
659
|
}
|
|
660
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
783
661
|
var tlvList = [];
|
|
784
662
|
data.forEach(function (value, index) {
|
|
785
663
|
if (index > 0) {
|
|
786
|
-
tlvList.push(255 /* SEPARATOR */, Buffer.alloc(0));
|
|
664
|
+
tlvList.push(255 /* TLVValues.SEPARATOR */, Buffer.alloc(0));
|
|
787
665
|
}
|
|
788
|
-
tlvList.push(1 /* IDENTIFIER */, value.username, 3 /* PUBLIC_KEY */, value.publicKey, 11 /* PERMISSIONS */, value.permission);
|
|
666
|
+
tlvList.push(1 /* TLVValues.IDENTIFIER */, value.username, 3 /* TLVValues.PUBLIC_KEY */, value.publicKey, 11 /* TLVValues.PERMISSIONS */, value.permission);
|
|
789
667
|
});
|
|
790
|
-
var list = tlv.encode.apply(tlv, tslib_1.__spreadArray([6 /* STATE */, 2 /* M2 */], tslib_1.__read(tlvList)));
|
|
791
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/pairing+tlv8" });
|
|
668
|
+
var list = tlv.encode.apply(tlv, tslib_1.__spreadArray([6 /* TLVValues.STATE */, 2 /* PairingStates.M2 */], tslib_1.__read(tlvList), false));
|
|
669
|
+
response.writeHead(200 /* HAPPairingHTTPCode.OK */, { "Content-Type": "application/pairing+tlv8" /* HAPMimeTypes.PAIRING_TLV8 */ });
|
|
792
670
|
response.end(list);
|
|
793
671
|
debug("[%s] Pairings: successfully executed LIST_PAIRINGS", _this.accessoryInfo.username);
|
|
794
672
|
}));
|
|
@@ -796,18 +674,18 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
796
674
|
};
|
|
797
675
|
HAPServer.prototype.handleAccessories = function (connection, url, request, data, response) {
|
|
798
676
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
799
|
-
response.writeHead(470 /* CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" });
|
|
800
|
-
response.end(JSON.stringify({ status: -70401 /* INSUFFICIENT_PRIVILEGES */ }));
|
|
677
|
+
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
678
|
+
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
801
679
|
return;
|
|
802
680
|
}
|
|
803
681
|
// call out to listeners to retrieve the latest accessories JSON
|
|
804
|
-
this.emit("accessories" /* ACCESSORIES */, connection, once_1.once(function (error, result) {
|
|
682
|
+
this.emit("accessories" /* HAPServerEventTypes.ACCESSORIES */, connection, (0, once_1.once)(function (error, result) {
|
|
805
683
|
if (error) {
|
|
806
|
-
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" });
|
|
684
|
+
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
807
685
|
response.end(JSON.stringify({ status: error.status }));
|
|
808
686
|
}
|
|
809
687
|
else {
|
|
810
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/hap+json" });
|
|
688
|
+
response.writeHead(200 /* HAPHTTPCode.OK */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
811
689
|
response.end(JSON.stringify(result));
|
|
812
690
|
}
|
|
813
691
|
}));
|
|
@@ -815,16 +693,16 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
815
693
|
HAPServer.prototype.handleCharacteristics = function (connection, url, request, data, response) {
|
|
816
694
|
var e_1, _a;
|
|
817
695
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
818
|
-
response.writeHead(470 /* CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" });
|
|
819
|
-
response.end(JSON.stringify({ status: -70401 /* INSUFFICIENT_PRIVILEGES */ }));
|
|
696
|
+
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
697
|
+
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
820
698
|
return;
|
|
821
699
|
}
|
|
822
700
|
if (request.method === "GET") {
|
|
823
701
|
var searchParams = url.searchParams;
|
|
824
702
|
var idParam = searchParams.get("id");
|
|
825
703
|
if (!idParam) {
|
|
826
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" });
|
|
827
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
704
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
705
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
828
706
|
return;
|
|
829
707
|
}
|
|
830
708
|
var ids = [];
|
|
@@ -834,7 +712,7 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
834
712
|
var split = entry.split("."); // ["1","9"]
|
|
835
713
|
ids.push({
|
|
836
714
|
aid: parseInt(split[0], 10),
|
|
837
|
-
iid: parseInt(split[1], 10), // (characteristic) instance
|
|
715
|
+
iid: parseInt(split[1], 10), // (characteristic) instance id
|
|
838
716
|
});
|
|
839
717
|
}
|
|
840
718
|
}
|
|
@@ -847,15 +725,15 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
847
725
|
}
|
|
848
726
|
var readRequest = {
|
|
849
727
|
ids: ids,
|
|
850
|
-
includeMeta: internal_types_1.consideredTrue(searchParams.get("meta")),
|
|
851
|
-
includePerms: internal_types_1.consideredTrue(searchParams.get("perms")),
|
|
852
|
-
includeType: internal_types_1.consideredTrue(searchParams.get("type")),
|
|
853
|
-
includeEvent: internal_types_1.consideredTrue(searchParams.get("ev")),
|
|
728
|
+
includeMeta: (0, internal_types_1.consideredTrue)(searchParams.get("meta")),
|
|
729
|
+
includePerms: (0, internal_types_1.consideredTrue)(searchParams.get("perms")),
|
|
730
|
+
includeType: (0, internal_types_1.consideredTrue)(searchParams.get("type")),
|
|
731
|
+
includeEvent: (0, internal_types_1.consideredTrue)(searchParams.get("ev")),
|
|
854
732
|
};
|
|
855
|
-
this.emit("get-characteristics" /* GET_CHARACTERISTICS */, connection, readRequest, once_1.once(function (error, readResponse) {
|
|
733
|
+
this.emit("get-characteristics" /* HAPServerEventTypes.GET_CHARACTERISTICS */, connection, readRequest, (0, once_1.once)(function (error, readResponse) {
|
|
856
734
|
var e_2, _a, e_3, _b;
|
|
857
735
|
if (error) {
|
|
858
|
-
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" });
|
|
736
|
+
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
859
737
|
response.end(JSON.stringify({ status: error.status }));
|
|
860
738
|
return;
|
|
861
739
|
}
|
|
@@ -882,7 +760,7 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
882
760
|
for (var characteristics_2 = tslib_1.__values(characteristics), characteristics_2_1 = characteristics_2.next(); !characteristics_2_1.done; characteristics_2_1 = characteristics_2.next()) {
|
|
883
761
|
var data_2 = characteristics_2_1.value;
|
|
884
762
|
if (!data_2.status) { // a status is undefined if the request was successful
|
|
885
|
-
data_2.status = 0 /* SUCCESS */; // a value of zero indicates success
|
|
763
|
+
data_2.status = 0 /* HAPStatus.SUCCESS */; // a value of zero indicates success
|
|
886
764
|
}
|
|
887
765
|
}
|
|
888
766
|
}
|
|
@@ -895,28 +773,28 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
895
773
|
}
|
|
896
774
|
}
|
|
897
775
|
// 207 "multi-status" is returned when an error occurs reading a characteristic. otherwise 200 is returned
|
|
898
|
-
response.writeHead(errorOccurred ? 207 /* MULTI_STATUS */ : 200 /* OK */, { "Content-Type": "application/hap+json" });
|
|
776
|
+
response.writeHead(errorOccurred ? 207 /* HAPHTTPCode.MULTI_STATUS */ : 200 /* HAPHTTPCode.OK */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
899
777
|
response.end(JSON.stringify({ characteristics: characteristics }));
|
|
900
778
|
}));
|
|
901
779
|
}
|
|
902
780
|
else if (request.method === "PUT") {
|
|
903
781
|
if (!connection.isAuthenticated()) {
|
|
904
|
-
if (!request.headers || (request.headers && request.headers
|
|
905
|
-
response.writeHead(470 /* CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" });
|
|
906
|
-
response.end(JSON.stringify({ status: -70401 /* INSUFFICIENT_PRIVILEGES */ }));
|
|
782
|
+
if (!request.headers || (request.headers && request.headers.authorization !== this.accessoryInfo.pincode)) {
|
|
783
|
+
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
784
|
+
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
907
785
|
return;
|
|
908
786
|
}
|
|
909
787
|
}
|
|
910
788
|
if (data.length === 0) {
|
|
911
|
-
response.writeHead(400
|
|
912
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
789
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
790
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
913
791
|
return;
|
|
914
792
|
}
|
|
915
793
|
var writeRequest = JSON.parse(data.toString("utf8"));
|
|
916
|
-
this.emit("set-characteristics" /* SET_CHARACTERISTICS */, connection, writeRequest, once_1.once(function (error, writeResponse) {
|
|
917
|
-
var e_4, _a
|
|
794
|
+
this.emit("set-characteristics" /* HAPServerEventTypes.SET_CHARACTERISTICS */, connection, writeRequest, (0, once_1.once)(function (error, writeResponse) {
|
|
795
|
+
var e_4, _a;
|
|
918
796
|
if (error) {
|
|
919
|
-
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" });
|
|
797
|
+
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
920
798
|
response.end(JSON.stringify({ status: error.status }));
|
|
921
799
|
return;
|
|
922
800
|
}
|
|
@@ -940,105 +818,91 @@ var HAPServer = /** @class */ (function (_super) {
|
|
|
940
818
|
finally { if (e_4) throw e_4.error; }
|
|
941
819
|
}
|
|
942
820
|
if (multiStatus) {
|
|
943
|
-
try {
|
|
944
|
-
for (var characteristics_4 = tslib_1.__values(characteristics), characteristics_4_1 = characteristics_4.next(); !characteristics_4_1.done; characteristics_4_1 = characteristics_4.next()) { // on a 207 Multi-Status EVERY characteristic MUST include a status property
|
|
945
|
-
var data_4 = characteristics_4_1.value;
|
|
946
|
-
if (data_4.status === undefined) {
|
|
947
|
-
data_4.status = 0 /* SUCCESS */;
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
952
|
-
finally {
|
|
953
|
-
try {
|
|
954
|
-
if (characteristics_4_1 && !characteristics_4_1.done && (_b = characteristics_4.return)) _b.call(characteristics_4);
|
|
955
|
-
}
|
|
956
|
-
finally { if (e_5) throw e_5.error; }
|
|
957
|
-
}
|
|
958
821
|
// 207 is "multi-status" since HomeKit may be setting multiple things and any one can fail independently
|
|
959
|
-
response.writeHead(207 /* MULTI_STATUS */, { "Content-Type": "application/hap+json" });
|
|
822
|
+
response.writeHead(207 /* HAPHTTPCode.MULTI_STATUS */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
960
823
|
response.end(JSON.stringify({ characteristics: characteristics }));
|
|
961
824
|
}
|
|
962
825
|
else {
|
|
963
826
|
// if everything went fine send 204 no content response
|
|
964
|
-
response.writeHead(204 /* NO_CONTENT */);
|
|
827
|
+
response.writeHead(204 /* HAPHTTPCode.NO_CONTENT */);
|
|
965
828
|
response.end();
|
|
966
829
|
}
|
|
967
830
|
}));
|
|
968
831
|
}
|
|
969
832
|
else {
|
|
970
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" }); // method not allowed
|
|
971
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
833
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ }); // method not allowed
|
|
834
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
972
835
|
}
|
|
973
836
|
};
|
|
974
837
|
HAPServer.prototype.handlePrepareWrite = function (connection, url, request, data, response) {
|
|
975
838
|
var _this = this;
|
|
976
839
|
if (!this.allowInsecureRequest && !connection.isAuthenticated()) {
|
|
977
|
-
response.writeHead(470 /* CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" });
|
|
978
|
-
response.end(JSON.stringify({ status: -70401 /* INSUFFICIENT_PRIVILEGES */ }));
|
|
840
|
+
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
841
|
+
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
979
842
|
return;
|
|
980
843
|
}
|
|
981
|
-
if (request.method
|
|
982
|
-
if (data.length
|
|
983
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" });
|
|
984
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
844
|
+
if (request.method === "PUT") {
|
|
845
|
+
if (data.length === 0) {
|
|
846
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
847
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
985
848
|
return;
|
|
986
849
|
}
|
|
987
850
|
var prepareRequest_1 = JSON.parse(data.toString());
|
|
988
851
|
if (prepareRequest_1.pid && prepareRequest_1.ttl) {
|
|
989
852
|
debug("[%s] Received prepare write request with pid %d and ttl %d", this.accessoryInfo.username, prepareRequest_1.pid, prepareRequest_1.ttl);
|
|
990
|
-
if (connection.timedWriteTimeout) // clear any currently existing timeouts
|
|
853
|
+
if (connection.timedWriteTimeout) { // clear any currently existing timeouts
|
|
991
854
|
clearTimeout(connection.timedWriteTimeout);
|
|
855
|
+
}
|
|
992
856
|
connection.timedWritePid = prepareRequest_1.pid;
|
|
993
857
|
connection.timedWriteTimeout = setTimeout(function () {
|
|
994
858
|
debug("[%s] Timed write request timed out for pid %d", _this.accessoryInfo.username, prepareRequest_1.pid);
|
|
995
859
|
connection.timedWritePid = undefined;
|
|
996
860
|
connection.timedWriteTimeout = undefined;
|
|
997
861
|
}, prepareRequest_1.ttl);
|
|
998
|
-
response.writeHead(200 /* OK */, { "Content-Type": "application/hap+json" });
|
|
999
|
-
response.end(JSON.stringify({ status: 0 /* SUCCESS */ }));
|
|
862
|
+
response.writeHead(200 /* HAPHTTPCode.OK */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
863
|
+
response.end(JSON.stringify({ status: 0 /* HAPStatus.SUCCESS */ }));
|
|
1000
864
|
return;
|
|
1001
865
|
}
|
|
1002
866
|
else {
|
|
1003
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" });
|
|
1004
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
867
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
868
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
1005
869
|
}
|
|
1006
870
|
}
|
|
1007
871
|
else {
|
|
1008
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" });
|
|
1009
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
872
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
873
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
1010
874
|
}
|
|
1011
875
|
};
|
|
1012
876
|
HAPServer.prototype.handleResource = function (connection, url, request, data, response) {
|
|
1013
877
|
if (!connection.isAuthenticated()) {
|
|
1014
878
|
if (!(this.allowInsecureRequest && request.headers && request.headers.authorization === this.accessoryInfo.pincode)) {
|
|
1015
|
-
response.writeHead(470 /* CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" });
|
|
1016
|
-
response.end(JSON.stringify({ status: -70401 /* INSUFFICIENT_PRIVILEGES */ }));
|
|
879
|
+
response.writeHead(470 /* HAPPairingHTTPCode.CONNECTION_AUTHORIZATION_REQUIRED */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
880
|
+
response.end(JSON.stringify({ status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ }));
|
|
1017
881
|
return;
|
|
1018
882
|
}
|
|
1019
883
|
}
|
|
1020
884
|
if (request.method === "POST") {
|
|
1021
885
|
if (data.length === 0) {
|
|
1022
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" });
|
|
1023
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
886
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
887
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
1024
888
|
return;
|
|
1025
889
|
}
|
|
1026
890
|
var resourceRequest = JSON.parse(data.toString());
|
|
1027
891
|
// call out to listeners to retrieve the resource, snapshot only right now
|
|
1028
|
-
this.emit("request-resource" /* REQUEST_RESOURCE */, resourceRequest, once_1.once(function (error, resource) {
|
|
892
|
+
this.emit("request-resource" /* HAPServerEventTypes.REQUEST_RESOURCE */, resourceRequest, (0, once_1.once)(function (error, resource) {
|
|
1029
893
|
if (error) {
|
|
1030
|
-
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" });
|
|
894
|
+
response.writeHead(error.httpCode, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ });
|
|
1031
895
|
response.end(JSON.stringify({ status: error.status }));
|
|
1032
896
|
}
|
|
1033
897
|
else {
|
|
1034
|
-
response.writeHead(200 /* OK */, { "Content-Type": "image/jpeg" });
|
|
898
|
+
response.writeHead(200 /* HAPHTTPCode.OK */, { "Content-Type": "image/jpeg" /* HAPMimeTypes.IMAGE_JPEG */ });
|
|
1035
899
|
response.end(resource);
|
|
1036
900
|
}
|
|
1037
901
|
}));
|
|
1038
902
|
}
|
|
1039
903
|
else {
|
|
1040
|
-
response.writeHead(400 /* BAD_REQUEST */, { "Content-Type": "application/hap+json" }); // method not allowed
|
|
1041
|
-
response.end(JSON.stringify({ status: -70410 /* INVALID_VALUE_IN_REQUEST */ }));
|
|
904
|
+
response.writeHead(400 /* HAPHTTPCode.BAD_REQUEST */, { "Content-Type": "application/hap+json" /* HAPMimeTypes.HAP_JSON */ }); // method not allowed
|
|
905
|
+
response.end(JSON.stringify({ status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ }));
|
|
1042
906
|
}
|
|
1043
907
|
};
|
|
1044
908
|
return HAPServer;
|