iobroker.tapo 0.3.3 → 0.3.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/README.md +4 -0
- package/build/lib/utils/energyUsage.js.map +1 -1
- package/build/lib/utils/l510e.js +3 -3
- package/build/lib/utils/l510e.js.map +2 -2
- package/build/lib/utils/l520e.js +3 -5
- package/build/lib/utils/l520e.js.map +2 -2
- package/build/lib/utils/l530.js +64 -24
- package/build/lib/utils/l530.js.map +2 -2
- package/build/lib/utils/newTpLinkCipher.js +33 -12
- package/build/lib/utils/newTpLinkCipher.js.map +3 -3
- package/build/lib/utils/p100.js +98 -113
- package/build/lib/utils/p100.js.map +3 -3
- package/build/lib/utils/p110.js +31 -15
- package/build/lib/utils/p110.js.map +2 -2
- package/build/lib/utils/powerUsage.js.map +1 -1
- package/build/lib/utils/tpLinkCipher.js +10 -3
- package/build/lib/utils/tpLinkCipher.js.map +3 -3
- package/build/lib/utils/tplinkAccessory.js +17 -0
- package/build/lib/utils/tplinkAccessory.js.map +7 -0
- package/build/lib/utils/usage.js.map +1 -1
- package/build/main.js +1 -1
- package/build/main.js.map +2 -2
- package/io-package.json +14 -5
- package/package.json +25 -20
package/README.md
CHANGED
|
@@ -32,6 +32,10 @@ tapo.0.id.remote auf true/false setzen steuert den jeweiligen Befehl. Der Befehl
|
|
|
32
32
|
<https://forum.iobroker.net/topic/57336/test-adapter-tp-link-tapo/>
|
|
33
33
|
|
|
34
34
|
## Changelog
|
|
35
|
+
### 0.3.4 (2024-11-10)
|
|
36
|
+
|
|
37
|
+
- update Tapo local lib
|
|
38
|
+
|
|
35
39
|
### 0.3.3 (2024-06-17)
|
|
36
40
|
|
|
37
41
|
- ignore ssl legacy error
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/energyUsage.ts"],
|
|
4
|
-
"sourcesContent": ["export class EnergyUsage{\n
|
|
4
|
+
"sourcesContent": ["export class EnergyUsage{\n current_power!: number;\n}"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,YAAW;AAExB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/lib/utils/l510e.js
CHANGED
|
@@ -27,7 +27,7 @@ __export(l510e_exports, {
|
|
|
27
27
|
default: () => L510E
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(l510e_exports);
|
|
30
|
-
var import_p100 = __toESM(require("./p100"));
|
|
30
|
+
var import_p100 = __toESM(require("./p100.js"));
|
|
31
31
|
class L510E extends import_p100.default {
|
|
32
32
|
constructor(log, ipAddress, email, password, timeout) {
|
|
33
33
|
super(log, ipAddress, email, password, timeout);
|
|
@@ -38,8 +38,8 @@ class L510E extends import_p100.default {
|
|
|
38
38
|
this.timeout = timeout;
|
|
39
39
|
this.log.debug("Constructing L510E on host: " + ipAddress);
|
|
40
40
|
}
|
|
41
|
-
async getDeviceInfo() {
|
|
42
|
-
return super.getDeviceInfo().then(() => {
|
|
41
|
+
async getDeviceInfo(force) {
|
|
42
|
+
return super.getDeviceInfo(force).then(() => {
|
|
43
43
|
return this.getSysInfo();
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/l510e.ts"],
|
|
4
|
-
"sourcesContent": ["import
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { LightSysinfo } from \"./types.js\";\nimport P100 from \"./p100.js\";\n\nexport default class L510E extends P100 {\n private _lightSysInfo!: LightSysinfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug(\"Constructing L510E on host: \" + ipAddress);\n }\n\n async getDeviceInfo(force?: boolean): Promise<LightSysinfo> {\n return super.getDeviceInfo(force).then(() => {\n return this.getSysInfo();\n });\n }\n\n async setBrightness(brightness: number): Promise<boolean> {\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"brightness\": ' +\n brightness +\n \"},\" +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n return this.sendRequest(payload);\n }\n\n protected setSysInfo(sysInfo: LightSysinfo) {\n this._lightSysInfo = sysInfo;\n this._lightSysInfo.last_update = Date.now();\n }\n\n public getSysInfo(): LightSysinfo {\n return this._lightSysInfo;\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAiB;AAEjB,MAAO,cAA4B,YAAAA,QAAK;AAAA,EAGtC,YACkB,KACA,WACA,OACA,UACA,SAChB;AACA,UAAM,KAAK,WAAW,OAAO,UAAU,OAAO;AAN9B;AACA;AACA;AACA;AACA;AAGhB,SAAK,IAAI,MAAM,iCAAiC,SAAS;AAAA,EAC3D;AAAA,EAEA,MAAM,cAAc,OAAwC;AAC1D,WAAO,MAAM,cAAc,KAAK,EAAE,KAAK,MAAM;AAC3C,aAAO,KAAK,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,YAAsC;AACxD,UAAM,UACJ,2DAIA,aACA,0BAEA,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAE5B;AAEF,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEU,WAAW,SAAuB;AAC1C,SAAK,gBAAgB;AACrB,SAAK,cAAc,cAAc,KAAK,IAAI;AAAA,EAC5C;AAAA,EAEO,aAA2B;AAChC,WAAO,KAAK;AAAA,EACd;AACF;",
|
|
6
6
|
"names": ["P100"]
|
|
7
7
|
}
|
package/build/lib/utils/l520e.js
CHANGED
|
@@ -38,8 +38,8 @@ class L520E extends import_l510e.default {
|
|
|
38
38
|
this.timeout = timeout;
|
|
39
39
|
this.log.debug("Constructing L510E on host: " + ipAddress);
|
|
40
40
|
}
|
|
41
|
-
async getDeviceInfo() {
|
|
42
|
-
return super.getDeviceInfo().then(() => {
|
|
41
|
+
async getDeviceInfo(force) {
|
|
42
|
+
return super.getDeviceInfo(force).then(() => {
|
|
43
43
|
return this.getSysInfo();
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -48,9 +48,7 @@ class L520E extends import_l510e.default {
|
|
|
48
48
|
this.log.debug("Color Temp Tapo :" + transformedColorTemp);
|
|
49
49
|
const roundedValue = transformedColorTemp > 6500 ? 6500 : transformedColorTemp < 2500 ? 2500 : transformedColorTemp;
|
|
50
50
|
const payload = '{"method": "set_device_info","params": {"hue": 0,"saturation": 0,"color_temp": ' + roundedValue + '},"requestTimeMils": ' + Math.round(Date.now() * 1e3) + "};";
|
|
51
|
-
return this.
|
|
52
|
-
return true;
|
|
53
|
-
});
|
|
51
|
+
return this.sendRequest(payload);
|
|
54
52
|
}
|
|
55
53
|
transformColorTemp(value) {
|
|
56
54
|
return Math.floor(1e6 / value);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/l520e.ts"],
|
|
4
|
-
"sourcesContent": ["import L510E from \"./l510e\";\nimport { ColorTempLightSysinfo } from \"./types\";\n\nexport default class L520E extends L510E {\n private _colorTempSysInfo!:
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAGlB,MAAO,cAA4B,aAAAA,QAAM;AAAA,
|
|
4
|
+
"sourcesContent": ["import L510E from \"./l510e\";\nimport { ColorTempLightSysinfo } from \"./types\";\n\nexport default class L520E extends L510E {\n\n private _colorTempSysInfo!:ColorTempLightSysinfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug('Constructing L510E on host: ' + ipAddress);\n }\n\n async getDeviceInfo(force?:boolean): Promise<ColorTempLightSysinfo>{\n return super.getDeviceInfo(force).then(() => {\n return this.getSysInfo();\n });\n }\n\n async setColorTemp(color_temp:number):Promise<boolean>{\n const transformedColorTemp = this.transformColorTemp(color_temp);\n this.log.debug('Color Temp Tapo :' + transformedColorTemp);\n\n const roundedValue = transformedColorTemp > 6500 ? 6500 : transformedColorTemp < 2500 ? \n 2500 : transformedColorTemp;\n\n const payload = '{'+\n '\"method\": \"set_device_info\",'+\n '\"params\": {'+\n '\"hue\": 0,' +\n '\"saturation\": 0,' +\n '\"color_temp\": ' + roundedValue +\n '},'+\n '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + ''+\n '};';\n\n return this.sendRequest(payload);\n }\n\n private transformColorTemp(value: number):number{\n return Math.floor(1000000 / value);\n }\n\n async getColorTemp(): Promise<number>{\n return super.getDeviceInfo().then(() => {\n return this.calculateColorTemp(this.getSysInfo().color_temp);\n });\n }\n\n calculateColorTemp(tapo_color_temp:number):number{\n const newValue = this.transformColorTemp(tapo_color_temp);\n return newValue > 400 ? 400 : (newValue < 154 ? 154 : newValue);\n }\n\n protected setSysInfo(sysInfo:ColorTempLightSysinfo){\n this._colorTempSysInfo = sysInfo;\n this._colorTempSysInfo.last_update = Date.now();\n }\n\n public getSysInfo():ColorTempLightSysinfo{\n return this._colorTempSysInfo;\n }\n}"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAGlB,MAAO,cAA4B,aAAAA,QAAM;AAAA,EAIvC,YACkB,KACA,WACA,OACA,UACA,SAChB;AACA,UAAM,KAAK,WAAW,OAAO,UAAU,OAAO;AAN9B;AACA;AACA;AACA;AACA;AAGhB,SAAK,IAAI,MAAM,iCAAiC,SAAS;AAAA,EAC3D;AAAA,EAEA,MAAM,cAAc,OAA+C;AACjE,WAAO,MAAM,cAAc,KAAK,EAAE,KAAK,MAAM;AAC3C,aAAO,KAAK,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,YAAmC;AACpD,UAAM,uBAAuB,KAAK,mBAAmB,UAAU;AAC/D,SAAK,IAAI,MAAM,sBAAsB,oBAAoB;AAEzD,UAAM,eAAe,uBAAuB,OAAO,OAAO,uBAAuB,OAC/E,OAAO;AAET,UAAM,UAAU,oFAKiB,eACnB,0BACwB,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IACpD;AAEd,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEQ,mBAAmB,OAAqB;AAC9C,WAAO,KAAK,MAAM,MAAU,KAAK;AAAA,EACnC;AAAA,EAEA,MAAM,eAA+B;AACnC,WAAO,MAAM,cAAc,EAAE,KAAK,MAAM;AACtC,aAAO,KAAK,mBAAmB,KAAK,WAAW,EAAE,UAAU;AAAA,IAC7D,CAAC;AAAA,EACH;AAAA,EAEA,mBAAmB,iBAA8B;AAC/C,UAAM,WAAW,KAAK,mBAAmB,eAAe;AACxD,WAAO,WAAW,MAAM,MAAO,WAAW,MAAM,MAAM;AAAA,EACxD;AAAA,EAEU,WAAW,SAA8B;AACjD,SAAK,oBAAoB;AACzB,SAAK,kBAAkB,cAAc,KAAK,IAAI;AAAA,EAChD;AAAA,EAEO,aAAkC;AACvC,WAAO,KAAK;AAAA,EACd;AACF;",
|
|
6
6
|
"names": ["L510E"]
|
|
7
7
|
}
|
package/build/lib/utils/l530.js
CHANGED
|
@@ -42,8 +42,8 @@ class L530 extends import_l520e.default {
|
|
|
42
42
|
current: 0
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
-
async getDeviceInfo() {
|
|
46
|
-
return super.getDeviceInfo().then(() => {
|
|
45
|
+
async getDeviceInfo(force) {
|
|
46
|
+
return super.getDeviceInfo(force).then(() => {
|
|
47
47
|
return this.getSysInfo();
|
|
48
48
|
});
|
|
49
49
|
}
|
|
@@ -54,6 +54,7 @@ class L530 extends import_l520e.default {
|
|
|
54
54
|
if (!saturation) {
|
|
55
55
|
saturation = 0;
|
|
56
56
|
}
|
|
57
|
+
this.log.debug("Setting color: " + hue + ", " + saturation);
|
|
57
58
|
const payload = '{"method": "set_device_info","params": {"hue": ' + Math.round(hue) + ',"color_temp": 0,"saturation": ' + Math.round(saturation) + '},"requestTimeMils": ' + Math.round(Date.now() * 1e3) + "};";
|
|
58
59
|
return this.sendRequest(payload);
|
|
59
60
|
}
|
|
@@ -66,33 +67,72 @@ class L530 extends import_l520e.default {
|
|
|
66
67
|
}
|
|
67
68
|
async getEnergyUsage() {
|
|
68
69
|
const payload = '{"method": "get_device_usage","requestTimeMils": ' + Math.round(Date.now() * 1e3) + "};";
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
70
|
+
this.log.debug("getEnergyUsage called");
|
|
71
|
+
if (this.is_klap) {
|
|
72
|
+
this.log.debug("getEnergyUsage is klap");
|
|
73
|
+
return this.handleKlapRequest(payload).then((response) => {
|
|
74
|
+
this.log.debug("Consumption: " + JSON.stringify(response));
|
|
75
|
+
if (response && response.result) {
|
|
76
|
+
this._consumption = {
|
|
77
|
+
total: response.result.power_usage.today / 1e3,
|
|
78
|
+
current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0
|
|
79
|
+
};
|
|
80
|
+
} else {
|
|
81
|
+
this._consumption = {
|
|
82
|
+
total: 0,
|
|
83
|
+
current: 0
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return response.result;
|
|
87
|
+
}).catch((error) => {
|
|
88
|
+
if (error.message && error.message.indexOf("9999") > 0) {
|
|
89
|
+
return this.reconnect().then(() => {
|
|
90
|
+
return this.handleKlapRequest(payload).then(() => {
|
|
91
|
+
return true;
|
|
92
|
+
});
|
|
87
93
|
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
return this.handleRequest(payload).then((response) => {
|
|
99
|
+
this.log.debug("Consumption: " + response);
|
|
100
|
+
if (response && response.result) {
|
|
101
|
+
this._consumption = {
|
|
102
|
+
total: response.result.power_usage.today / 1e3,
|
|
103
|
+
current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0
|
|
104
|
+
};
|
|
105
|
+
} else {
|
|
106
|
+
this._consumption = {
|
|
107
|
+
total: 0,
|
|
108
|
+
current: 0
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return response.result;
|
|
112
|
+
}).catch((error) => {
|
|
113
|
+
if (error.message && error.message.indexOf("9999") > 0) {
|
|
114
|
+
return this.reconnect().then(() => {
|
|
115
|
+
return this.handleRequest(payload).then(() => {
|
|
116
|
+
return true;
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
92
123
|
}
|
|
93
124
|
getPowerConsumption() {
|
|
125
|
+
if (!this.getSysInfo().device_on) {
|
|
126
|
+
return {
|
|
127
|
+
total: this._consumption.total,
|
|
128
|
+
current: 0
|
|
129
|
+
};
|
|
130
|
+
}
|
|
94
131
|
return this._consumption;
|
|
95
132
|
}
|
|
133
|
+
toHours(minutes) {
|
|
134
|
+
return minutes / 60;
|
|
135
|
+
}
|
|
96
136
|
}
|
|
97
137
|
// Annotate the CommonJS export names for ESM import in node:
|
|
98
138
|
0 && (module.exports = {});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/l530.ts"],
|
|
4
|
-
"sourcesContent": ["import L520E from \"./l520e\";\nimport { PowerUsage } from \"./powerUsage\";\nimport { ColorLightSysinfo, ConsumptionInfo } from \"./types\";\n\nexport default class L530 extends L520E {\n private _colorLightSysInfo!:
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAIlB,MAAO,aAA2B,aAAAA,QAAM;AAAA,
|
|
4
|
+
"sourcesContent": ["import L520E from \"./l520e\";\nimport { PowerUsage } from \"./powerUsage\";\nimport { ColorLightSysinfo, ConsumptionInfo } from \"./types\";\n\nexport default class L530 extends L520E {\n\n private _colorLightSysInfo!:ColorLightSysinfo;\n private _consumption!:ConsumptionInfo;\n\n constructor(\n public readonly log: any,\n public readonly ipAddress: string,\n public readonly email: string,\n public readonly password: string,\n public readonly timeout: number,\n ) {\n super(log, ipAddress, email, password, timeout);\n this.log.debug('Constructing L530 on host: ' + ipAddress);\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n\n async getDeviceInfo(force?:boolean): Promise<ColorLightSysinfo>{\n return super.getDeviceInfo(force).then(() => {\n return this.getSysInfo();\n });\n }\n\n async setColor(hue:number, saturation:number):Promise<boolean>{\n if(!hue){\n hue = 0;\n }\n if(!saturation){\n saturation = 0;\n }\n this.log.debug('Setting color: ' + hue + ', ' + saturation);\n const payload = '{'+\n '\"method\": \"set_device_info\",'+\n '\"params\": {'+\n '\"hue\": ' + Math.round(hue) + ','+\n '\"color_temp\": 0,' +\n '\"saturation\": ' + Math.round(saturation) +\n '},'+\n '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + ''+\n '};';\n\n return this.sendRequest(payload);\n }\n\n protected setSysInfo(sysInfo:ColorLightSysinfo){\n this._colorLightSysInfo = sysInfo;\n this._colorLightSysInfo.last_update = Date.now();\n }\n\n public getSysInfo():ColorLightSysinfo{\n return this._colorLightSysInfo;\n }\n\n async getEnergyUsage():Promise<PowerUsage>{ \n const payload = '{'+\n '\"method\": \"get_device_usage\",'+\n '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + ''+\n '};';\n this.log.debug('getEnergyUsage called');\n\n if(this.is_klap){\n this.log.debug('getEnergyUsage is klap');\n\n return this.handleKlapRequest(payload).then((response)=>{\n this.log.debug('Consumption: ' + JSON.stringify(response));\n if(response && response.result){\n this._consumption = {\n total: response.result.power_usage.today / 1000,\n current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0,\n };\n } else{\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n \n return response.result;\n }).catch((error)=>{\n if(error.message && error.message.indexOf('9999') > 0){\n return this.reconnect().then(()=>{\n return this.handleKlapRequest(payload).then(()=>{\n return true;\n });\n });\n }\n return false;\n });\n }else{\n return this.handleRequest(payload).then((response)=>{\n this.log.debug('Consumption: ' + response);\n if(response && response.result){\n this._consumption = {\n total: response.result.power_usage.today / 1000,\n current: this._consumption ? response.result.power_usage.today / this.toHours(response.result.time_usage.today) : 0,\n };\n } else{\n this._consumption = {\n total: 0,\n current: 0,\n };\n }\n \n return response.result;\n }).catch((error)=>{\n if(error.message && error.message.indexOf('9999') > 0){\n return this.reconnect().then(()=>{\n return this.handleRequest(payload).then(()=>{\n return true;\n });\n });\n }\n return false;\n });\n }\n \n }\n\n public getPowerConsumption():ConsumptionInfo{\n if(!this.getSysInfo().device_on){\n return {\n total: this._consumption.total,\n current: 0,\n };\n }\n return this._consumption;\n }\n\n private toHours(minutes: number):number{\n return minutes/60;\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["L520E"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,29 +17,37 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
18
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
25
|
var newTpLinkCipher_exports = {};
|
|
20
26
|
__export(newTpLinkCipher_exports, {
|
|
21
27
|
default: () => NewTpLinkCipher
|
|
22
28
|
});
|
|
23
29
|
module.exports = __toCommonJS(newTpLinkCipher_exports);
|
|
30
|
+
var import_crypto = __toESM(require("crypto"));
|
|
24
31
|
class NewTpLinkCipher {
|
|
25
|
-
constructor(localSeed, remoteSeed, authHash) {
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
constructor(localSeed, remoteSeed, authHash, log) {
|
|
33
|
+
this.log = log;
|
|
34
|
+
this._crypto = import_crypto.default;
|
|
35
|
+
if (authHash) {
|
|
36
|
+
this.calculateKey(localSeed, remoteSeed, authHash);
|
|
37
|
+
this.calculateIvSeq(localSeed, remoteSeed, authHash);
|
|
38
|
+
this.calculateSig(localSeed, remoteSeed, authHash);
|
|
39
|
+
}
|
|
30
40
|
}
|
|
31
41
|
encrypt(data) {
|
|
32
42
|
this.seq += 1;
|
|
33
43
|
if (typeof data === "string") {
|
|
34
44
|
data = Buffer.from(data, "utf8");
|
|
35
45
|
}
|
|
36
|
-
const cipher = this.
|
|
46
|
+
const cipher = this._crypto.createCipheriv("aes-128-cbc", this.key, this.ivSeqPair());
|
|
37
47
|
const cipherText = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
38
48
|
const seqBuffer = Buffer.alloc(4);
|
|
39
49
|
seqBuffer.writeInt32BE(this.seq, 0);
|
|
40
|
-
const hash = this.
|
|
50
|
+
const hash = this._crypto.createHash("sha256");
|
|
41
51
|
hash.update(Buffer.concat([this.sig, seqBuffer, cipherText]));
|
|
42
52
|
const signature = hash.digest();
|
|
43
53
|
return {
|
|
@@ -46,24 +56,35 @@ class NewTpLinkCipher {
|
|
|
46
56
|
};
|
|
47
57
|
}
|
|
48
58
|
decrypt(data) {
|
|
49
|
-
const decipher = this.
|
|
59
|
+
const decipher = this._crypto.createDecipheriv("aes-128-cbc", this.key, this.ivSeqPair());
|
|
50
60
|
const decrypted = Buffer.concat([decipher.update(data.subarray(32)), decipher.final()]);
|
|
51
|
-
|
|
61
|
+
const dec = decrypted.toString("utf8");
|
|
62
|
+
this.log.debug("decrypted: " + dec);
|
|
63
|
+
let dec_fixed = "";
|
|
64
|
+
if (dec.match(/{"error_code":([-0-9]+)[^,}]$/)) {
|
|
65
|
+
dec_fixed = dec.replace(/{"error_code":([-0-9]+)[^,}]/gm, '{"error_code":"$1"}');
|
|
66
|
+
} else if (dec.match(/{"error_code":([-0-9]+)}$/)) {
|
|
67
|
+
dec_fixed = dec.replace(/{"error_code":([-0-9]+)}$/gm, '{"error_code":"$1"}');
|
|
68
|
+
} else {
|
|
69
|
+
dec_fixed = dec.replace(/{"error_code":([-0-9]+)[^,}](.*)/gm, '{"error_code":"$1",$2');
|
|
70
|
+
}
|
|
71
|
+
this.log.debug("decrypted fixed: " + dec_fixed);
|
|
72
|
+
return dec_fixed;
|
|
52
73
|
}
|
|
53
74
|
calculateKey(local_seed, remote_seed, auth_hash) {
|
|
54
75
|
const buf = Buffer.concat([Buffer.from("lsk"), local_seed, remote_seed, auth_hash]);
|
|
55
|
-
const hash = this.
|
|
76
|
+
const hash = this._crypto.createHash("sha256").update(buf).digest();
|
|
56
77
|
this.key = hash.subarray(0, 16);
|
|
57
78
|
}
|
|
58
79
|
calculateIvSeq(local_seed, remote_seed, auth_hash) {
|
|
59
80
|
const buf = Buffer.concat([Buffer.from("iv"), local_seed, remote_seed, auth_hash]);
|
|
60
|
-
const ivBuf = this.
|
|
81
|
+
const ivBuf = this._crypto.createHash("sha256").update(buf).digest();
|
|
61
82
|
this.seq = ivBuf.subarray(-4).readInt32BE(0);
|
|
62
83
|
this.iv = ivBuf.subarray(0, 12);
|
|
63
84
|
}
|
|
64
85
|
calculateSig(local_seed, remote_seed, auth_hash) {
|
|
65
86
|
const payload = Buffer.concat([Buffer.from("ldk"), local_seed, remote_seed, auth_hash]);
|
|
66
|
-
this.sig = this.
|
|
87
|
+
this.sig = this._crypto.createHash("sha256").update(payload).digest().subarray(0, 28);
|
|
67
88
|
}
|
|
68
89
|
ivSeqPair() {
|
|
69
90
|
const seq = Buffer.alloc(4);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/newTpLinkCipher.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import crypto from \"crypto\";\n\nexport default class NewTpLinkCipher {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public iv: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public key: any;\n private _crypto = crypto;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public sig: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public seq: any;\n\n constructor(\n localSeed: Buffer,\n remoteSeed: Buffer,\n authHash: Buffer | undefined,\n public readonly log: any,\n ) {\n if (authHash) {\n this.calculateKey(localSeed, remoteSeed, authHash);\n this.calculateIvSeq(localSeed, remoteSeed, authHash);\n this.calculateSig(localSeed, remoteSeed, authHash);\n }\n }\n\n public encrypt(data: Buffer | string) {\n this.seq += 1;\n\n if (typeof data === \"string\") {\n data = Buffer.from(data, \"utf8\");\n }\n\n const cipher = this._crypto.createCipheriv(\"aes-128-cbc\", this.key, this.ivSeqPair());\n const cipherText = Buffer.concat([cipher.update(data), cipher.final()]);\n\n const seqBuffer = Buffer.alloc(4);\n seqBuffer.writeInt32BE(this.seq, 0);\n\n const hash = this._crypto.createHash(\"sha256\");\n hash.update(Buffer.concat([this.sig, seqBuffer, cipherText]));\n\n const signature = hash.digest();\n\n return {\n encryptedPayload: Buffer.concat([signature, cipherText]),\n seq: this.seq,\n };\n }\n\n public decrypt(data: Buffer) {\n const decipher = this._crypto.createDecipheriv(\"aes-128-cbc\", this.key, this.ivSeqPair());\n const decrypted = Buffer.concat([decipher.update(data.subarray(32)), decipher.final()]);\n\n const dec = decrypted.toString(\"utf8\");\n this.log.debug(\"decrypted: \" + dec);\n\n //Some times the json returned is malformed, or the number returned in error_code\n //is not valid e.g. -0301, so we need to use regex to replace the malformed/invalid json parts\n let dec_fixed = \"\";\n if (dec.match(/{\"error_code\":([-0-9]+)[^,}]$/)) {\n dec_fixed = dec.replace(/{\"error_code\":([-0-9]+)[^,}]/gm, '{\"error_code\":\"$1\"}');\n } else if (dec.match(/{\"error_code\":([-0-9]+)}$/)) {\n dec_fixed = dec.replace(/{\"error_code\":([-0-9]+)}$/gm, '{\"error_code\":\"$1\"}');\n } else {\n dec_fixed = dec.replace(/{\"error_code\":([-0-9]+)[^,}](.*)/gm, '{\"error_code\":\"$1\",$2');\n }\n\n this.log.debug(\"decrypted fixed: \" + dec_fixed);\n\n return dec_fixed;\n }\n\n private calculateKey(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const buf = Buffer.concat([Buffer.from(\"lsk\"), local_seed, remote_seed, auth_hash]);\n const hash = this._crypto.createHash(\"sha256\").update(buf).digest();\n this.key = hash.subarray(0, 16);\n }\n\n private calculateIvSeq(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const buf = Buffer.concat([Buffer.from(\"iv\"), local_seed, remote_seed, auth_hash]);\n const ivBuf = this._crypto.createHash(\"sha256\").update(buf).digest();\n this.seq = ivBuf.subarray(-4).readInt32BE(0);\n this.iv = ivBuf.subarray(0, 12);\n }\n\n private calculateSig(local_seed: Buffer, remote_seed: Buffer, auth_hash: Buffer) {\n const payload = Buffer.concat([Buffer.from(\"ldk\"), local_seed, remote_seed, auth_hash]);\n this.sig = this._crypto.createHash(\"sha256\").update(payload).digest().subarray(0, 28);\n }\n\n private ivSeqPair() {\n const seq = Buffer.alloc(4);\n seq.writeInt32BE(this.seq, 0);\n return Buffer.concat([this.iv, seq]);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["crypto"]
|
|
7
7
|
}
|