iobroker.tapo 0.4.2 → 0.4.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 +5 -1
- package/build/lib/utils/p100.js +7 -2
- package/build/lib/utils/p100.js.map +2 -2
- package/io-package.json +20 -94
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -32,7 +32,11 @@ 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.4.
|
|
35
|
+
### 0.4.4 (2024-12-12)
|
|
36
|
+
|
|
37
|
+
- improve handshake if e-mail is not entered in lowercase
|
|
38
|
+
|
|
39
|
+
### 0.4.3 (2024-12-09)
|
|
36
40
|
|
|
37
41
|
- fix handshake for device with HW v1.20
|
|
38
42
|
|
package/build/lib/utils/p100.js
CHANGED
|
@@ -342,6 +342,9 @@ class P100 {
|
|
|
342
342
|
if (validateAuthHash(this.email, this.password)) {
|
|
343
343
|
this.log.debug("New Handshake 1 successful");
|
|
344
344
|
auth_hash = ah;
|
|
345
|
+
} else if (validateAuthHash(this.email.toLowerCase(), this.password)) {
|
|
346
|
+
this.log.debug("New Handshake 1 successful with lowercase mail");
|
|
347
|
+
auth_hash = ah;
|
|
345
348
|
} else if (validateAuthHash("", "")) {
|
|
346
349
|
this.log.debug("New Handshake 1 successful with empty auth hash");
|
|
347
350
|
auth_hash = this.calc_auth_hash("", "");
|
|
@@ -349,8 +352,10 @@ class P100 {
|
|
|
349
352
|
this.log.debug("New Handshake 1 successful with test auth hash");
|
|
350
353
|
auth_hash = this.calc_auth_hash("test@tp-link.net", "test");
|
|
351
354
|
} else {
|
|
352
|
-
this.log.
|
|
353
|
-
this.log.
|
|
355
|
+
this.log.error("New Handshake 1 failed");
|
|
356
|
+
this.log.error(
|
|
357
|
+
"Local seed auth hash doesn't match server hash. Please check if the mail and password are correct. And E-Mail is in same Upper/Lowercase as in the Tapo App"
|
|
358
|
+
);
|
|
354
359
|
auth_hash = ah;
|
|
355
360
|
}
|
|
356
361
|
const req = this._crypto.createHash("sha256").update(Buffer.concat([remote_seed, local_seed, auth_hash])).digest();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/p100.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { PlugSysinfo } from \"./types\";\nimport TpLinkCipher from \"./tpLinkCipher.js\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { AxiosResponse } from \"axios\";\nimport NewTpLinkCipher from \"./newTpLinkCipher.js\";\nimport { TpLinkAccessory } from \"./tplinkAccessory.js\";\nimport axios from \"axios\";\nimport crypto from \"crypto\";\nimport utf8 from \"utf8\";\n\nimport http from \"http\";\n\nexport default class P100 implements TpLinkAccessory {\n private _crypto = crypto;\n protected _axios = axios;\n private _utf8 = utf8;\n public is_klap = true;\n\n private encodedPassword!: string;\n private encodedEmail!: string;\n private privateKey!: string;\n private publicKey!: string;\n protected ip: string;\n protected cookie!: string;\n protected tplink_timeout!: number;\n protected token!: string;\n protected terminalUUID: string;\n private _plugSysInfo!: PlugSysinfo;\n private _reconnect_counter: number;\n protected _timeout!: number;\n\n protected tpLinkCipher!: TpLinkCipher;\n protected newTpLinkCipher!: NewTpLinkCipher;\n\n protected ERROR_CODES = {\n \"0\": \"Success\",\n \"-1010\": \"Invalid Public Key Length\",\n \"-1012\": \"Invalid terminalUUID\",\n \"-1501\": \"Invalid Request or Credentials\",\n \"1002\": \"Incorrect Request\",\n \"-1003\": \"JSON formatting error \",\n \"9999\": \"Session Timeout\",\n \"-1301\": \"Device Error\",\n \"1100\": \"Handshake Failed\",\n \"1111\": \"Login Failed\",\n \"1112\": \"Http Transport Failed\",\n \"1200\": \"Multiple Requests Failed\",\n \"-1004\": \"JSON Encode Failed\",\n \"-1005\": \"AES Decode Failed\",\n \"-1006\": \"Request Length Error\",\n \"-2101\": \"Account Error\",\n \"-1\": \"ERR_COMMON_FAILED\",\n \"1000\": \"ERR_NULL_TRANSPORT\",\n \"1001\": \"ERR_CMD_COMMAND_CANCEL\",\n \"-1001\": \"ERR_UNSPECIFIC\",\n \"-1002\": \"ERR_UNKNOWN_METHOD\",\n \"-1007\": \"ERR_CLOUD_FAILED\",\n \"-1008\": \"ERR_PARAMS\",\n \"-1101\": \"ERR_SESSION_PARAM\",\n \"-1201\": \"ERR_QUICK_SETUP\",\n \"-1302\": \"ERR_DEVICE_NEXT_EVENT\",\n \"-1401\": \"ERR_FIRMWARE\",\n \"-1402\": \"ERR_FIRMWARE_VER_ERROR\",\n \"-1601\": \"ERR_TIME\",\n \"-1602\": \"ERR_TIME_SYS\",\n \"-1603\": \"ERR_TIME_SAVE\",\n \"-1701\": \"ERR_WIRELESS\",\n \"-1702\": \"ERR_WIRELESS_UNSUPPORTED\",\n \"-1801\": \"ERR_SCHEDULE\",\n \"-1802\": \"ERR_SCHEDULE_FULL\",\n \"-1803\": \"ERR_SCHEDULE_CONFLICT\",\n \"-1804\": \"ERR_SCHEDULE_SAVE\",\n \"-1805\": \"ERR_SCHEDULE_INDEX\",\n \"-1901\": \"ERR_COUNTDOWN\",\n \"-1902\": \"ERR_COUNTDOWN_CONFLICT\",\n \"-1903\": \"ERR_COUNTDOWN_SAVE\",\n \"-2001\": \"ERR_ANTITHEFT\",\n \"-2002\": \"ERR_ANTITHEFT_CONFLICT\",\n \"-2003\": \"ERR_ANTITHEFT_SAVE\",\n \"-2201\": \"ERR_STAT\",\n \"-2202\": \"ERR_STAT_SAVE\",\n \"-2301\": \"ERR_DST\",\n \"-2302\": \"ERR_DST_SAVE\",\n \"1003\": \"KLAP\",\n };\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 this.log.debug(\"Constructing P100 on host: \" + ipAddress);\n this.ip = ipAddress;\n this.encryptCredentials(email, password);\n this.createKeyPair();\n this.terminalUUID = uuidv4();\n this._reconnect_counter = 0;\n this._timeout = timeout;\n }\n\n private encryptCredentials(email: string, password: string) {\n //Password Encoding\n this.encodedPassword = TpLinkCipher.mime_encoder(password);\n\n //Email Encoding\n this.encodedEmail = this.sha_digest_username(email);\n this.encodedEmail = TpLinkCipher.mime_encoder(this.encodedEmail);\n }\n\n private sha_digest_username(data: string): string {\n const digest = this._crypto.createHash(\"sha1\").update(data).digest(\"hex\");\n\n return digest;\n }\n\n private calc_auth_hash(username: string, password: string): Buffer {\n const usernameDigest = this._crypto\n .createHash(\"sha1\")\n .update(Buffer.from(username.normalize(\"NFKC\")))\n .digest();\n const passwordDigest = this._crypto\n .createHash(\"sha1\")\n .update(Buffer.from(password.normalize(\"NFKC\")))\n .digest();\n const digest = this._crypto\n .createHash(\"sha256\")\n .update(Buffer.concat([usernameDigest, passwordDigest]))\n .digest();\n return digest;\n }\n\n private createKeyPair() {\n // Including publicKey and privateKey from\n // generateKeyPairSync() method with its\n // parameters\n const { publicKey, privateKey } = this._crypto.generateKeyPairSync(\"rsa\", {\n publicKeyEncoding: {\n type: \"spki\",\n format: \"pem\",\n },\n privateKeyEncoding: {\n type: \"pkcs1\",\n format: \"pem\",\n },\n modulusLength: 1024,\n });\n\n this.privateKey = privateKey;\n //@ts-ignore\n this.publicKey = publicKey.toString(\"utf8\");\n }\n\n //old tapo requests\n async handshake(): Promise<void> {\n const URL = \"http://\" + this.ip + \"/app\";\n const payload = {\n method: \"handshake\",\n params: {\n key: this.publicKey,\n requestTimeMils: Math.round(Date.now() * 1000),\n },\n };\n this.log.debug(\"Old Handshake P100 on host: \" + this.ip);\n\n const headers = {\n Connection: \"Keep-Alive\",\n };\n const config = {\n timeout: 5000,\n headers: headers,\n };\n\n await this._axios\n .post(URL, payload, config)\n .then((res: AxiosResponse) => {\n this.log.debug(\"Received Old Handshake P100 on host response: \" + this.ip);\n\n if (res.data.error_code || res.status !== 200) {\n return this.handleError(res.data!.error_code ? res.data.error_code : res.status, \"172\");\n }\n\n try {\n const encryptedKey = res.data.result.key.toString(\"utf8\");\n this.decode_handshake_key(encryptedKey);\n if (res.headers[\"set-cookie\"]) {\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n }\n return;\n } catch (error) {\n return this.handleError(res.data.error_code, \"106\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"111 Error: \" + error ? error.message : \"\");\n return error;\n });\n }\n\n async login(): Promise<void> {\n const URL = \"http://\" + this.ip + \"/app\";\n const payload =\n \"{\" +\n '\"method\": \"login_device\",' +\n '\"params\": {' +\n '\"username\": \"' +\n this.encodedEmail +\n '\",' +\n '\"password\": \"' +\n this.encodedPassword +\n '\"' +\n \"},\" +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n const headers = {\n Cookie: this.cookie,\n Connection: \"Keep-Alive\",\n };\n\n this.log.debug(\"Old Login to P100 with url \" + URL);\n this.log.debug(\"Headers \" + JSON.stringify(headers));\n this.log.debug(\"Cipher: \" + this.tpLinkCipher);\n if (this.tpLinkCipher) {\n const encryptedPayload = this.tpLinkCipher.encrypt(payload);\n\n const securePassthroughPayload = {\n method: \"securePassthrough\",\n params: {\n request: encryptedPayload,\n },\n };\n\n const config = {\n headers: headers,\n timeout: this._timeout * 1000,\n };\n this.log.debug(\"Post request\");\n await this._axios\n .post(URL, securePassthroughPayload, config)\n .then((res: AxiosResponse) => {\n if (res.data.error_code || res.status !== 200) {\n return this.handleError(res.data!.error_code ? res.data.error_code : res.status, \"226\");\n }\n const decryptedResponse = this.tpLinkCipher.decrypt(res.data.result.response);\n this.log.debug(\"Decrypted Response: \" + decryptedResponse);\n try {\n const response = JSON.parse(decryptedResponse);\n if (response.error_code !== 0) {\n return this.handleError(res.data.error_code, \"152\");\n }\n this.token = response.result.token;\n return;\n } catch (error) {\n return this.handleError(JSON.parse(decryptedResponse).error_code, \"157\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"Error Login: \" + error ? error.message : \"\");\n return error;\n });\n }\n }\n\n private async raw_request(path: string, data: Buffer, responseType: string, params?: any): Promise<any> {\n const URL = \"http://\" + this.ip + \"/app/\" + path;\n\n const headers = {\n Connection: \"Keep-Alive\",\n Host: this.ip,\n Accept: \"*/*\",\n \"Content-Type\": \"application/octet-stream\",\n };\n\n if (this.cookie) {\n //@ts-ignore\n headers.Cookie = this.cookie;\n }\n\n const config = {\n timeout: 5000,\n responseType: responseType,\n headers: headers,\n params: params,\n };\n this.log.debug(\"Raw request to P100 with url \" + URL);\n this.log.debug(\"Data: \" + data.toString(\"hex\"));\n this.log.debug(\"Headers: \" + JSON.stringify(headers));\n this.log.debug(\"Params: \" + JSON.stringify(params));\n this.log.debug(\"Cipher: \" + this.tpLinkCipher);\n\n //@ts-ignore\n return this._axios\n .post(URL, data, config)\n .then((res: AxiosResponse) => {\n this.log.debug(\"Received request on host response: \" + this.ip);\n if (res.data.error_code || res.status !== 200) {\n return this.handleError(res.data!.error_code ? res.data.error_code : res.status, \"273\");\n }\n\n try {\n if (res.headers && res.headers[\"set-cookie\"]) {\n this.log.debug(\"Handshake 1 cookie: \" + JSON.stringify(res.headers[\"set-cookie\"][0]));\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n this.tplink_timeout = Number(res.headers[\"set-cookie\"][0].split(\";\")[1]);\n }\n return res.data;\n } catch (error) {\n return this.handleError(res.data.error_code, \"318\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"276 Error: \" + error.message);\n if (error.message.indexOf(\"403\") > -1) {\n this.reAuthenticate();\n }\n return error;\n });\n }\n\n private decode_handshake_key(key: string) {\n const buff = Buffer.from(key, \"base64\");\n\n const decoded = this._crypto.privateDecrypt(\n {\n key: this.privateKey,\n padding: this._crypto.constants.RSA_PKCS1_PADDING,\n },\n buff,\n );\n\n const b_arr = decoded.slice(0, 16);\n const b_arr2 = decoded.slice(16, 32);\n\n this.tpLinkCipher = new TpLinkCipher(this.log, b_arr, b_arr2);\n }\n\n //new tapo klap requests\n async handshake_new(): Promise<void> {\n this.log.debug(\"Trying new handshake\");\n\n const local_seed = this._crypto.randomBytes(16);\n\n const ah = this.calc_auth_hash(this.email, this.password);\n //send handshake1 via native http\n\n const options: http.RequestOptions = {\n method: \"POST\",\n hostname: this.ip,\n path: \"/app/handshake1\",\n headers: {\n Connection: \"Keep-Alive\",\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Length\": local_seed.length,\n },\n agent: new http.Agent({\n keepAlive: true,\n }),\n };\n const response = await new Promise<Buffer>((resolve, reject) => {\n const request = http\n .request(options, (res: any) => {\n let chunks: any = [];\n if (res.headers && res.headers[\"set-cookie\"]) {\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n }\n res.on(\"data\", (chunk: any) => {\n chunks.push(chunk);\n });\n\n res.on(\"end\", (chunk: any) => {\n var body = Buffer.concat(chunks);\n this.log.debug(body.toString());\n resolve(body);\n });\n\n res.on(\"error\", (error: any) => {\n this.log.error(error);\n resolve(Buffer.from(\"\"));\n });\n })\n .on(\"error\", (error: any) => {\n this.log.error(error);\n resolve(Buffer.from(\"\"));\n });\n request.write(local_seed);\n request.end();\n });\n // const response = await this.raw_request(\"handshake1\", local_seed, \"arraybuffer\").then((res) => {\n //axios not working for handshake1\n if (!response || !response.subarray) {\n this.log.debug(\"New Handshake 1 failed\");\n return;\n }\n this.log.debug(\"Handshake 1 response: \" + response.toString(\"hex\"));\n const remote_seed: Buffer = response.subarray(0, 16);\n const server_hash: Buffer = response.subarray(16);\n this.log.debug(\"remote seed: \" + remote_seed.toString(\"hex\"));\n this.log.debug(\"server hash: \" + server_hash.toString(\"hex\"));\n this.log.debug(\"Extracted hashes\");\n let auth_hash: any = undefined;\n this.log.debug(\"Calculated auth hash: \" + ah.toString(\"hex\"));\n const calculateAuthHash = (email: string, password: string) => {\n return this._crypto\n .createHash(\"sha256\")\n .update(Buffer.concat([local_seed, remote_seed, this.calc_auth_hash(email, password)]))\n .digest();\n };\n\n const local_seed_auth_hash = calculateAuthHash(this.email, this.password);\n this.log.debug(\"Calculated local seed auth hash: \" + local_seed_auth_hash.toString(\"hex\"));\n this.log.debug(\"Server hash: \" + server_hash.toString(\"hex\"));\n\n const validateAuthHash = (email: string, password: string): boolean => {\n const calculatedHash = calculateAuthHash(email, password);\n this.log.debug(`Calculated auth hash for ${email}: ${calculatedHash.toString(\"hex\")}`);\n return calculatedHash.toString(\"hex\") === server_hash.toString(\"hex\");\n };\n\n if (validateAuthHash(this.email, this.password)) {\n this.log.debug(\"New Handshake 1 successful\");\n auth_hash = ah;\n } else if (validateAuthHash(\"\", \"\")) {\n this.log.debug(\"New Handshake 1 successful with empty auth hash\");\n auth_hash = this.calc_auth_hash(\"\", \"\");\n } else if (validateAuthHash(\"test@tp-link.net\", \"test\")) {\n this.log.debug(\"New Handshake 1 successful with test auth hash\");\n auth_hash = this.calc_auth_hash(\"test@tp-link.net\", \"test\");\n } else {\n this.log.debug(\"New Handshake 1 failed\");\n this.log.debug(\"Local seed auth hash doesn't match server hash\");\n auth_hash = ah;\n }\n const req = this._crypto\n .createHash(\"sha256\")\n .update(Buffer.concat([remote_seed, local_seed, auth_hash]))\n .digest();\n\n return this.raw_request(\"handshake2\", req, \"text\").then((res) => {\n this.log.debug(\"New Handshake 2 successful: \" + res);\n\n this.newTpLinkCipher = new NewTpLinkCipher(local_seed, remote_seed, auth_hash, this.log);\n this.log.debug(\"New Init cipher successful\");\n\n return;\n });\n // });\n }\n\n async turnOff(): Promise<boolean> {\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"device_on\": false' +\n \"},\" +\n '\"terminalUUID\": \"' +\n this.terminalUUID +\n '\",' +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n return this.sendRequest(payload);\n }\n\n async turnOn(): Promise<boolean> {\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"device_on\": true' +\n \"},\" +\n '\"terminalUUID\": \"' +\n this.terminalUUID +\n '\",' +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n return this.sendRequest(payload);\n }\n\n async setPowerState(state: boolean): Promise<boolean> {\n if (state) {\n return this.turnOn();\n } else {\n return this.turnOff();\n }\n }\n\n async getDeviceInfo(force?: boolean): Promise<PlugSysinfo> {\n if (!force) {\n return new Promise((resolve) => {\n resolve(this.getSysInfo());\n });\n }\n const URL = \"http://\" + this.ip + \"/app?token=\" + this.token;\n\n const payload = \"{\" + '\"method\": \"get_device_info\",' + '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + \"\" + \"};\";\n const headers = {\n Cookie: this.cookie,\n };\n\n if (this.tpLinkCipher) {\n const encryptedPayload = this.tpLinkCipher.encrypt(payload);\n\n const securePassthroughPayload = {\n method: \"securePassthrough\",\n params: {\n request: encryptedPayload,\n },\n };\n\n const config = {\n headers: headers,\n timeout: this._timeout * 1000,\n };\n //@ts-ignore\n return this._axios\n .post(URL, securePassthroughPayload, config)\n .then((res: any) => {\n if (res.data.error_code) {\n if ((res.data.error_code === \"9999\" || res.data.error_code === 9999) && this._reconnect_counter <= 3) {\n //@ts-ignore\n this.log.error(\" Error Code: \" + res.data.error_code + \", \" + this.ERROR_CODES[res.data.error_code]);\n this.log.debug(\"Trying to reconnect...\");\n return this.reconnect().then(() => {\n return this.getDeviceInfo();\n });\n }\n this._reconnect_counter = 0;\n return this.handleError(res.data.error_code, \"326\");\n }\n\n const decryptedResponse = this.tpLinkCipher.decrypt(res.data.result.response);\n try {\n const response = JSON.parse(decryptedResponse);\n if (response.error_code !== 0) {\n return this.handleError(response.error_code, \"333\");\n }\n this.setSysInfo(response.result);\n this.log.debug(\"Device Info: \", response.result);\n\n return this.getSysInfo();\n } catch (error) {\n this.log.debug(error.stack);\n return this.handleError(JSON.parse(decryptedResponse).error_code, \"340\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"371 Error: \" + error ? error.message : \"\");\n return error;\n });\n } else if (this.newTpLinkCipher) {\n const data = this.newTpLinkCipher.encrypt(payload);\n\n const URL = \"http://\" + this.ip + \"/app/\" + \"request\";\n const headers = {\n Connection: \"Keep-Alive\",\n Host: this.ip,\n Accept: \"*/*\",\n \"Content-Type\": \"application/octet-stream\",\n };\n\n if (this.cookie) {\n //@ts-ignore\n headers.Cookie = this.cookie;\n }\n\n const config = {\n timeout: 5000,\n responseType: \"arraybuffer\",\n headers: headers,\n params: { seq: data.seq.toString() },\n };\n //@ts-ignore\n return this._axios\n .post(URL, data.encryptedPayload, config)\n .then((res: AxiosResponse) => {\n if (res.data.error_code) {\n return this.handleError(res.data.error_code, \"309\");\n }\n\n try {\n if (res.headers && res.headers[\"set-cookie\"]) {\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n }\n\n const response = JSON.parse(this.newTpLinkCipher.decrypt(res.data));\n\n if (response.error_code !== 0) {\n return this.handleError(response.error_code, \"333\");\n }\n this.setSysInfo(response.result);\n this.log.debug(\"Device Info: \", response.result);\n\n return this.getSysInfo();\n } catch (error) {\n this.log.debug(this.newTpLinkCipher.decrypt(res.data));\n this.log.debug(\"Status: \" + res.status);\n return this.handleError(res.data.error_code, \"480\");\n }\n })\n .catch((error: Error) => {\n this.log.debug(\"469 Error: \" + JSON.stringify(error));\n this.log.info(\"469 Error: \" + error.message);\n if (error.message.indexOf(\"403\") > -1) {\n this.reAuthenticate();\n }\n return error;\n });\n } else {\n return new Promise<PlugSysinfo>((resolve, reject) => {\n reject();\n });\n }\n }\n\n /**\n * Cached value of `sysinfo.device_id` if set.\n */\n get id(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().device_id;\n }\n return \"\";\n }\n\n /**\n * Cached value of `sysinfo.device_id` if set.\n */\n get name(): string {\n if (this.getSysInfo()) {\n return Buffer.from(this.getSysInfo().nickname, \"base64\").toString(\"utf8\");\n }\n return \"\";\n }\n\n get model(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().model;\n }\n return \"\";\n }\n\n get serialNumber(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().hw_id;\n }\n return \"\";\n }\n\n get firmwareRevision(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().fw_ver;\n }\n return \"\";\n }\n\n get hardwareRevision(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().hw_ver;\n }\n return \"\";\n }\n\n protected setSysInfo(sysInfo: PlugSysinfo) {\n this._plugSysInfo = sysInfo;\n this._plugSysInfo.last_update = Date.now();\n }\n\n public getSysInfo(): PlugSysinfo {\n return this._plugSysInfo;\n }\n\n protected handleError(errorCode: number | string, line: string): boolean {\n //@ts-ignore\n const errorMessage = this.ERROR_CODES[errorCode];\n if (typeof errorCode === \"number\" && errorCode === 1003) {\n this.log.info(\"Trying KLAP Auth\");\n this.is_klap = true;\n } else {\n this.log.error(line + \" Error Code: \" + errorCode + \", \" + errorMessage + \" \" + this.ip);\n }\n return false;\n }\n\n protected async sendRequest(payload: string): Promise<boolean> {\n if (this.tpLinkCipher) {\n return this.handleRequest(payload)\n .then((result) => {\n return result ? true : false;\n })\n .catch((error) => {\n if (error.message && error.message.indexOf(\"9999\") > 0 && this._reconnect_counter <= 3) {\n return this.reconnect().then(() => {\n return this.handleRequest(payload).then((result) => {\n return result ? true : false;\n });\n });\n }\n this._reconnect_counter = 0;\n return false;\n });\n } else {\n return this.handleKlapRequest(payload)\n .then((result) => {\n return result ? true : false;\n })\n .catch((error) => {\n if (error.message && error.message.indexOf(\"9999\") > 0 && this._reconnect_counter <= 3) {\n return this.newReconnect().then(() => {\n return this.handleKlapRequest(payload).then((result) => {\n return result ? true : false;\n });\n });\n }\n this._reconnect_counter = 0;\n return false;\n });\n }\n }\n\n protected handleRequest(payload: string): Promise<any> {\n const URL = \"http://\" + this.ip + \"/app?token=\" + this.token;\n\n const headers = {\n Cookie: this.cookie,\n Connection: \"Keep-Alive\",\n };\n\n if (this.tpLinkCipher) {\n const encryptedPayload = this.tpLinkCipher.encrypt(payload);\n\n const securePassthroughPayload = {\n method: \"securePassthrough\",\n params: {\n request: encryptedPayload,\n },\n };\n\n const config = {\n headers: headers,\n timeout: this._timeout * 1000,\n };\n\n return this._axios\n .post(URL, securePassthroughPayload, config)\n .then((res: AxiosResponse) => {\n if (res.data.error_code) {\n if (res.data.error_code === \"9999\" || (res.data.error_code === 9999 && this._reconnect_counter <= 3)) {\n //@ts-ignore\n this.log.error(\" Error Code: \" + res.data.error_code + \", \" + this.ERROR_CODES[res.data.error_code]);\n this.log.debug(\"Trying to reconnect...\");\n return this.reconnect().then(() => {\n return this.getDeviceInfo();\n });\n }\n this._reconnect_counter = 0;\n return this.handleError(res.data.error_code, \"357\");\n }\n\n const decryptedResponse = this.tpLinkCipher.decrypt(res.data.result.response);\n try {\n const response = JSON.parse(decryptedResponse);\n this.log.debug(response);\n if (response.error_code !== 0) {\n return this.handleError(response.error_code, \"364\");\n }\n return response;\n } catch (error) {\n return this.handleError(JSON.parse(decryptedResponse).error_code, \"368\");\n }\n })\n .catch((error: Error) => {\n return this.handleError(error.message, \"656\");\n });\n }\n return new Promise<true>((resolve, reject) => {\n reject();\n });\n }\n\n protected handleKlapRequest(payload: string): Promise<any> {\n if (this.newTpLinkCipher) {\n const data = this.newTpLinkCipher.encrypt(payload);\n\n return this.raw_request(\"request\", data.encryptedPayload, \"arraybuffer\", { seq: data.seq.toString() })\n .then((res) => {\n return JSON.parse(this.newTpLinkCipher.decrypt(res));\n })\n .catch((error: Error) => {\n return this.handleError(error.message, \"671\");\n });\n }\n return new Promise<true>((resolve, reject) => {\n reject();\n });\n }\n\n protected async reconnect(): Promise<void> {\n this._reconnect_counter++;\n return this.handshake().then(() => {\n this.login().then(() => {\n return;\n });\n });\n }\n\n protected async newReconnect(): Promise<void> {\n this._reconnect_counter++;\n return this.handshake_new().then(() => {\n return;\n });\n }\n\n private reAuthenticate(): void {\n this.log.debug(\"Reauthenticating\");\n if (this.is_klap) {\n this.handshake_new()\n .then(() => {\n this.log.info(\"KLAP Authenticated successfully\");\n })\n .catch(() => {\n this.log.error(\"KLAP Handshake New failed\");\n this.is_klap = false;\n });\n } else {\n this.handshake().then(() => {\n this.login()\n .then(() => {\n this.log.info(\"Authenticated successfully\");\n })\n .catch(() => {\n this.log.error(\"Login failed\");\n });\n });\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { PlugSysinfo } from \"./types\";\nimport TpLinkCipher from \"./tpLinkCipher.js\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { AxiosResponse } from \"axios\";\nimport NewTpLinkCipher from \"./newTpLinkCipher.js\";\nimport { TpLinkAccessory } from \"./tplinkAccessory.js\";\nimport axios from \"axios\";\nimport crypto from \"crypto\";\nimport utf8 from \"utf8\";\n\nimport http from \"http\";\n\nexport default class P100 implements TpLinkAccessory {\n private _crypto = crypto;\n protected _axios = axios;\n private _utf8 = utf8;\n public is_klap = true;\n\n private encodedPassword!: string;\n private encodedEmail!: string;\n private privateKey!: string;\n private publicKey!: string;\n protected ip: string;\n protected cookie!: string;\n protected tplink_timeout!: number;\n protected token!: string;\n protected terminalUUID: string;\n private _plugSysInfo!: PlugSysinfo;\n private _reconnect_counter: number;\n protected _timeout!: number;\n\n protected tpLinkCipher!: TpLinkCipher;\n protected newTpLinkCipher!: NewTpLinkCipher;\n\n protected ERROR_CODES = {\n \"0\": \"Success\",\n \"-1010\": \"Invalid Public Key Length\",\n \"-1012\": \"Invalid terminalUUID\",\n \"-1501\": \"Invalid Request or Credentials\",\n \"1002\": \"Incorrect Request\",\n \"-1003\": \"JSON formatting error \",\n \"9999\": \"Session Timeout\",\n \"-1301\": \"Device Error\",\n \"1100\": \"Handshake Failed\",\n \"1111\": \"Login Failed\",\n \"1112\": \"Http Transport Failed\",\n \"1200\": \"Multiple Requests Failed\",\n \"-1004\": \"JSON Encode Failed\",\n \"-1005\": \"AES Decode Failed\",\n \"-1006\": \"Request Length Error\",\n \"-2101\": \"Account Error\",\n \"-1\": \"ERR_COMMON_FAILED\",\n \"1000\": \"ERR_NULL_TRANSPORT\",\n \"1001\": \"ERR_CMD_COMMAND_CANCEL\",\n \"-1001\": \"ERR_UNSPECIFIC\",\n \"-1002\": \"ERR_UNKNOWN_METHOD\",\n \"-1007\": \"ERR_CLOUD_FAILED\",\n \"-1008\": \"ERR_PARAMS\",\n \"-1101\": \"ERR_SESSION_PARAM\",\n \"-1201\": \"ERR_QUICK_SETUP\",\n \"-1302\": \"ERR_DEVICE_NEXT_EVENT\",\n \"-1401\": \"ERR_FIRMWARE\",\n \"-1402\": \"ERR_FIRMWARE_VER_ERROR\",\n \"-1601\": \"ERR_TIME\",\n \"-1602\": \"ERR_TIME_SYS\",\n \"-1603\": \"ERR_TIME_SAVE\",\n \"-1701\": \"ERR_WIRELESS\",\n \"-1702\": \"ERR_WIRELESS_UNSUPPORTED\",\n \"-1801\": \"ERR_SCHEDULE\",\n \"-1802\": \"ERR_SCHEDULE_FULL\",\n \"-1803\": \"ERR_SCHEDULE_CONFLICT\",\n \"-1804\": \"ERR_SCHEDULE_SAVE\",\n \"-1805\": \"ERR_SCHEDULE_INDEX\",\n \"-1901\": \"ERR_COUNTDOWN\",\n \"-1902\": \"ERR_COUNTDOWN_CONFLICT\",\n \"-1903\": \"ERR_COUNTDOWN_SAVE\",\n \"-2001\": \"ERR_ANTITHEFT\",\n \"-2002\": \"ERR_ANTITHEFT_CONFLICT\",\n \"-2003\": \"ERR_ANTITHEFT_SAVE\",\n \"-2201\": \"ERR_STAT\",\n \"-2202\": \"ERR_STAT_SAVE\",\n \"-2301\": \"ERR_DST\",\n \"-2302\": \"ERR_DST_SAVE\",\n \"1003\": \"KLAP\",\n };\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 this.log.debug(\"Constructing P100 on host: \" + ipAddress);\n this.ip = ipAddress;\n this.encryptCredentials(email, password);\n this.createKeyPair();\n this.terminalUUID = uuidv4();\n this._reconnect_counter = 0;\n this._timeout = timeout;\n }\n\n private encryptCredentials(email: string, password: string) {\n //Password Encoding\n this.encodedPassword = TpLinkCipher.mime_encoder(password);\n\n //Email Encoding\n this.encodedEmail = this.sha_digest_username(email);\n this.encodedEmail = TpLinkCipher.mime_encoder(this.encodedEmail);\n }\n\n private sha_digest_username(data: string): string {\n const digest = this._crypto.createHash(\"sha1\").update(data).digest(\"hex\");\n\n return digest;\n }\n\n private calc_auth_hash(username: string, password: string): Buffer {\n const usernameDigest = this._crypto\n .createHash(\"sha1\")\n .update(Buffer.from(username.normalize(\"NFKC\")))\n .digest();\n const passwordDigest = this._crypto\n .createHash(\"sha1\")\n .update(Buffer.from(password.normalize(\"NFKC\")))\n .digest();\n const digest = this._crypto\n .createHash(\"sha256\")\n .update(Buffer.concat([usernameDigest, passwordDigest]))\n .digest();\n return digest;\n }\n\n private createKeyPair() {\n // Including publicKey and privateKey from\n // generateKeyPairSync() method with its\n // parameters\n const { publicKey, privateKey } = this._crypto.generateKeyPairSync(\"rsa\", {\n publicKeyEncoding: {\n type: \"spki\",\n format: \"pem\",\n },\n privateKeyEncoding: {\n type: \"pkcs1\",\n format: \"pem\",\n },\n modulusLength: 1024,\n });\n\n this.privateKey = privateKey;\n //@ts-ignore\n this.publicKey = publicKey.toString(\"utf8\");\n }\n\n //old tapo requests\n async handshake(): Promise<void> {\n const URL = \"http://\" + this.ip + \"/app\";\n const payload = {\n method: \"handshake\",\n params: {\n key: this.publicKey,\n requestTimeMils: Math.round(Date.now() * 1000),\n },\n };\n this.log.debug(\"Old Handshake P100 on host: \" + this.ip);\n\n const headers = {\n Connection: \"Keep-Alive\",\n };\n const config = {\n timeout: 5000,\n headers: headers,\n };\n\n await this._axios\n .post(URL, payload, config)\n .then((res: AxiosResponse) => {\n this.log.debug(\"Received Old Handshake P100 on host response: \" + this.ip);\n\n if (res.data.error_code || res.status !== 200) {\n return this.handleError(res.data!.error_code ? res.data.error_code : res.status, \"172\");\n }\n\n try {\n const encryptedKey = res.data.result.key.toString(\"utf8\");\n this.decode_handshake_key(encryptedKey);\n if (res.headers[\"set-cookie\"]) {\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n }\n return;\n } catch (error) {\n return this.handleError(res.data.error_code, \"106\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"111 Error: \" + error ? error.message : \"\");\n return error;\n });\n }\n\n async login(): Promise<void> {\n const URL = \"http://\" + this.ip + \"/app\";\n const payload =\n \"{\" +\n '\"method\": \"login_device\",' +\n '\"params\": {' +\n '\"username\": \"' +\n this.encodedEmail +\n '\",' +\n '\"password\": \"' +\n this.encodedPassword +\n '\"' +\n \"},\" +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n const headers = {\n Cookie: this.cookie,\n Connection: \"Keep-Alive\",\n };\n\n this.log.debug(\"Old Login to P100 with url \" + URL);\n this.log.debug(\"Headers \" + JSON.stringify(headers));\n this.log.debug(\"Cipher: \" + this.tpLinkCipher);\n if (this.tpLinkCipher) {\n const encryptedPayload = this.tpLinkCipher.encrypt(payload);\n\n const securePassthroughPayload = {\n method: \"securePassthrough\",\n params: {\n request: encryptedPayload,\n },\n };\n\n const config = {\n headers: headers,\n timeout: this._timeout * 1000,\n };\n this.log.debug(\"Post request\");\n await this._axios\n .post(URL, securePassthroughPayload, config)\n .then((res: AxiosResponse) => {\n if (res.data.error_code || res.status !== 200) {\n return this.handleError(res.data!.error_code ? res.data.error_code : res.status, \"226\");\n }\n const decryptedResponse = this.tpLinkCipher.decrypt(res.data.result.response);\n this.log.debug(\"Decrypted Response: \" + decryptedResponse);\n try {\n const response = JSON.parse(decryptedResponse);\n if (response.error_code !== 0) {\n return this.handleError(res.data.error_code, \"152\");\n }\n this.token = response.result.token;\n return;\n } catch (error) {\n return this.handleError(JSON.parse(decryptedResponse).error_code, \"157\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"Error Login: \" + error ? error.message : \"\");\n return error;\n });\n }\n }\n\n private async raw_request(path: string, data: Buffer, responseType: string, params?: any): Promise<any> {\n const URL = \"http://\" + this.ip + \"/app/\" + path;\n\n const headers = {\n Connection: \"Keep-Alive\",\n Host: this.ip,\n Accept: \"*/*\",\n \"Content-Type\": \"application/octet-stream\",\n };\n\n if (this.cookie) {\n //@ts-ignore\n headers.Cookie = this.cookie;\n }\n\n const config = {\n timeout: 5000,\n responseType: responseType,\n headers: headers,\n params: params,\n };\n this.log.debug(\"Raw request to P100 with url \" + URL);\n this.log.debug(\"Data: \" + data.toString(\"hex\"));\n this.log.debug(\"Headers: \" + JSON.stringify(headers));\n this.log.debug(\"Params: \" + JSON.stringify(params));\n this.log.debug(\"Cipher: \" + this.tpLinkCipher);\n\n //@ts-ignore\n return this._axios\n .post(URL, data, config)\n .then((res: AxiosResponse) => {\n this.log.debug(\"Received request on host response: \" + this.ip);\n if (res.data.error_code || res.status !== 200) {\n return this.handleError(res.data!.error_code ? res.data.error_code : res.status, \"273\");\n }\n\n try {\n if (res.headers && res.headers[\"set-cookie\"]) {\n this.log.debug(\"Handshake 1 cookie: \" + JSON.stringify(res.headers[\"set-cookie\"][0]));\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n this.tplink_timeout = Number(res.headers[\"set-cookie\"][0].split(\";\")[1]);\n }\n return res.data;\n } catch (error) {\n return this.handleError(res.data.error_code, \"318\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"276 Error: \" + error.message);\n if (error.message.indexOf(\"403\") > -1) {\n this.reAuthenticate();\n }\n return error;\n });\n }\n\n private decode_handshake_key(key: string) {\n const buff = Buffer.from(key, \"base64\");\n\n const decoded = this._crypto.privateDecrypt(\n {\n key: this.privateKey,\n padding: this._crypto.constants.RSA_PKCS1_PADDING,\n },\n buff,\n );\n\n const b_arr = decoded.slice(0, 16);\n const b_arr2 = decoded.slice(16, 32);\n\n this.tpLinkCipher = new TpLinkCipher(this.log, b_arr, b_arr2);\n }\n\n //new tapo klap requests\n async handshake_new(): Promise<void> {\n this.log.debug(\"Trying new handshake\");\n\n const local_seed = this._crypto.randomBytes(16);\n\n const ah = this.calc_auth_hash(this.email, this.password);\n //send handshake1 via native http\n\n const options: http.RequestOptions = {\n method: \"POST\",\n hostname: this.ip,\n path: \"/app/handshake1\",\n headers: {\n Connection: \"Keep-Alive\",\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Length\": local_seed.length,\n },\n agent: new http.Agent({\n keepAlive: true,\n }),\n };\n const response = await new Promise<Buffer>((resolve, reject) => {\n const request = http\n .request(options, (res: any) => {\n let chunks: any = [];\n if (res.headers && res.headers[\"set-cookie\"]) {\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n }\n res.on(\"data\", (chunk: any) => {\n chunks.push(chunk);\n });\n\n res.on(\"end\", (chunk: any) => {\n var body = Buffer.concat(chunks);\n this.log.debug(body.toString());\n resolve(body);\n });\n\n res.on(\"error\", (error: any) => {\n this.log.error(error);\n resolve(Buffer.from(\"\"));\n });\n })\n .on(\"error\", (error: any) => {\n this.log.error(error);\n resolve(Buffer.from(\"\"));\n });\n request.write(local_seed);\n request.end();\n });\n // const response = await this.raw_request(\"handshake1\", local_seed, \"arraybuffer\").then((res) => {\n //axios not working for handshake1\n if (!response || !response.subarray) {\n this.log.debug(\"New Handshake 1 failed\");\n return;\n }\n this.log.debug(\"Handshake 1 response: \" + response.toString(\"hex\"));\n const remote_seed: Buffer = response.subarray(0, 16);\n const server_hash: Buffer = response.subarray(16);\n this.log.debug(\"remote seed: \" + remote_seed.toString(\"hex\"));\n this.log.debug(\"server hash: \" + server_hash.toString(\"hex\"));\n this.log.debug(\"Extracted hashes\");\n let auth_hash: any = undefined;\n this.log.debug(\"Calculated auth hash: \" + ah.toString(\"hex\"));\n const calculateAuthHash = (email: string, password: string) => {\n return this._crypto\n .createHash(\"sha256\")\n .update(Buffer.concat([local_seed, remote_seed, this.calc_auth_hash(email, password)]))\n .digest();\n };\n\n const local_seed_auth_hash = calculateAuthHash(this.email, this.password);\n this.log.debug(\"Calculated local seed auth hash: \" + local_seed_auth_hash.toString(\"hex\"));\n this.log.debug(\"Server hash: \" + server_hash.toString(\"hex\"));\n\n const validateAuthHash = (email: string, password: string): boolean => {\n const calculatedHash = calculateAuthHash(email, password);\n this.log.debug(`Calculated auth hash for ${email}: ${calculatedHash.toString(\"hex\")}`);\n return calculatedHash.toString(\"hex\") === server_hash.toString(\"hex\");\n };\n\n if (validateAuthHash(this.email, this.password)) {\n this.log.debug(\"New Handshake 1 successful\");\n auth_hash = ah;\n } else if (validateAuthHash(this.email.toLowerCase(), this.password)) {\n this.log.debug(\"New Handshake 1 successful with lowercase mail\");\n auth_hash = ah;\n } else if (validateAuthHash(\"\", \"\")) {\n this.log.debug(\"New Handshake 1 successful with empty auth hash\");\n auth_hash = this.calc_auth_hash(\"\", \"\");\n } else if (validateAuthHash(\"test@tp-link.net\", \"test\")) {\n this.log.debug(\"New Handshake 1 successful with test auth hash\");\n auth_hash = this.calc_auth_hash(\"test@tp-link.net\", \"test\");\n } else {\n this.log.error(\"New Handshake 1 failed\");\n this.log.error(\n \"Local seed auth hash doesn't match server hash. Please check if the mail and password are correct. And E-Mail is in same Upper/Lowercase as in the Tapo App\",\n );\n auth_hash = ah;\n }\n const req = this._crypto\n .createHash(\"sha256\")\n .update(Buffer.concat([remote_seed, local_seed, auth_hash]))\n .digest();\n\n return this.raw_request(\"handshake2\", req, \"text\").then((res) => {\n this.log.debug(\"New Handshake 2 successful: \" + res);\n\n this.newTpLinkCipher = new NewTpLinkCipher(local_seed, remote_seed, auth_hash, this.log);\n this.log.debug(\"New Init cipher successful\");\n\n return;\n });\n // });\n }\n\n async turnOff(): Promise<boolean> {\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"device_on\": false' +\n \"},\" +\n '\"terminalUUID\": \"' +\n this.terminalUUID +\n '\",' +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n return this.sendRequest(payload);\n }\n\n async turnOn(): Promise<boolean> {\n const payload =\n \"{\" +\n '\"method\": \"set_device_info\",' +\n '\"params\": {' +\n '\"device_on\": true' +\n \"},\" +\n '\"terminalUUID\": \"' +\n this.terminalUUID +\n '\",' +\n '\"requestTimeMils\": ' +\n Math.round(Date.now() * 1000) +\n \"\" +\n \"};\";\n\n return this.sendRequest(payload);\n }\n\n async setPowerState(state: boolean): Promise<boolean> {\n if (state) {\n return this.turnOn();\n } else {\n return this.turnOff();\n }\n }\n\n async getDeviceInfo(force?: boolean): Promise<PlugSysinfo> {\n if (!force) {\n return new Promise((resolve) => {\n resolve(this.getSysInfo());\n });\n }\n const URL = \"http://\" + this.ip + \"/app?token=\" + this.token;\n\n const payload = \"{\" + '\"method\": \"get_device_info\",' + '\"requestTimeMils\": ' + Math.round(Date.now() * 1000) + \"\" + \"};\";\n const headers = {\n Cookie: this.cookie,\n };\n\n if (this.tpLinkCipher) {\n const encryptedPayload = this.tpLinkCipher.encrypt(payload);\n\n const securePassthroughPayload = {\n method: \"securePassthrough\",\n params: {\n request: encryptedPayload,\n },\n };\n\n const config = {\n headers: headers,\n timeout: this._timeout * 1000,\n };\n //@ts-ignore\n return this._axios\n .post(URL, securePassthroughPayload, config)\n .then((res: any) => {\n if (res.data.error_code) {\n if ((res.data.error_code === \"9999\" || res.data.error_code === 9999) && this._reconnect_counter <= 3) {\n //@ts-ignore\n this.log.error(\" Error Code: \" + res.data.error_code + \", \" + this.ERROR_CODES[res.data.error_code]);\n this.log.debug(\"Trying to reconnect...\");\n return this.reconnect().then(() => {\n return this.getDeviceInfo();\n });\n }\n this._reconnect_counter = 0;\n return this.handleError(res.data.error_code, \"326\");\n }\n\n const decryptedResponse = this.tpLinkCipher.decrypt(res.data.result.response);\n try {\n const response = JSON.parse(decryptedResponse);\n if (response.error_code !== 0) {\n return this.handleError(response.error_code, \"333\");\n }\n this.setSysInfo(response.result);\n this.log.debug(\"Device Info: \", response.result);\n\n return this.getSysInfo();\n } catch (error) {\n this.log.debug(error.stack);\n return this.handleError(JSON.parse(decryptedResponse).error_code, \"340\");\n }\n })\n .catch((error: Error) => {\n this.log.error(\"371 Error: \" + error ? error.message : \"\");\n return error;\n });\n } else if (this.newTpLinkCipher) {\n const data = this.newTpLinkCipher.encrypt(payload);\n\n const URL = \"http://\" + this.ip + \"/app/\" + \"request\";\n const headers = {\n Connection: \"Keep-Alive\",\n Host: this.ip,\n Accept: \"*/*\",\n \"Content-Type\": \"application/octet-stream\",\n };\n\n if (this.cookie) {\n //@ts-ignore\n headers.Cookie = this.cookie;\n }\n\n const config = {\n timeout: 5000,\n responseType: \"arraybuffer\",\n headers: headers,\n params: { seq: data.seq.toString() },\n };\n //@ts-ignore\n return this._axios\n .post(URL, data.encryptedPayload, config)\n .then((res: AxiosResponse) => {\n if (res.data.error_code) {\n return this.handleError(res.data.error_code, \"309\");\n }\n\n try {\n if (res.headers && res.headers[\"set-cookie\"]) {\n this.cookie = res.headers[\"set-cookie\"][0].split(\";\")[0];\n }\n\n const response = JSON.parse(this.newTpLinkCipher.decrypt(res.data));\n\n if (response.error_code !== 0) {\n return this.handleError(response.error_code, \"333\");\n }\n this.setSysInfo(response.result);\n this.log.debug(\"Device Info: \", response.result);\n\n return this.getSysInfo();\n } catch (error) {\n this.log.debug(this.newTpLinkCipher.decrypt(res.data));\n this.log.debug(\"Status: \" + res.status);\n return this.handleError(res.data.error_code, \"480\");\n }\n })\n .catch((error: Error) => {\n this.log.debug(\"469 Error: \" + JSON.stringify(error));\n this.log.info(\"469 Error: \" + error.message);\n if (error.message.indexOf(\"403\") > -1) {\n this.reAuthenticate();\n }\n return error;\n });\n } else {\n return new Promise<PlugSysinfo>((resolve, reject) => {\n reject();\n });\n }\n }\n\n /**\n * Cached value of `sysinfo.device_id` if set.\n */\n get id(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().device_id;\n }\n return \"\";\n }\n\n /**\n * Cached value of `sysinfo.device_id` if set.\n */\n get name(): string {\n if (this.getSysInfo()) {\n return Buffer.from(this.getSysInfo().nickname, \"base64\").toString(\"utf8\");\n }\n return \"\";\n }\n\n get model(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().model;\n }\n return \"\";\n }\n\n get serialNumber(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().hw_id;\n }\n return \"\";\n }\n\n get firmwareRevision(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().fw_ver;\n }\n return \"\";\n }\n\n get hardwareRevision(): string {\n if (this.getSysInfo()) {\n return this.getSysInfo().hw_ver;\n }\n return \"\";\n }\n\n protected setSysInfo(sysInfo: PlugSysinfo) {\n this._plugSysInfo = sysInfo;\n this._plugSysInfo.last_update = Date.now();\n }\n\n public getSysInfo(): PlugSysinfo {\n return this._plugSysInfo;\n }\n\n protected handleError(errorCode: number | string, line: string): boolean {\n //@ts-ignore\n const errorMessage = this.ERROR_CODES[errorCode];\n if (typeof errorCode === \"number\" && errorCode === 1003) {\n this.log.info(\"Trying KLAP Auth\");\n this.is_klap = true;\n } else {\n this.log.error(line + \" Error Code: \" + errorCode + \", \" + errorMessage + \" \" + this.ip);\n }\n return false;\n }\n\n protected async sendRequest(payload: string): Promise<boolean> {\n if (this.tpLinkCipher) {\n return this.handleRequest(payload)\n .then((result) => {\n return result ? true : false;\n })\n .catch((error) => {\n if (error.message && error.message.indexOf(\"9999\") > 0 && this._reconnect_counter <= 3) {\n return this.reconnect().then(() => {\n return this.handleRequest(payload).then((result) => {\n return result ? true : false;\n });\n });\n }\n this._reconnect_counter = 0;\n return false;\n });\n } else {\n return this.handleKlapRequest(payload)\n .then((result) => {\n return result ? true : false;\n })\n .catch((error) => {\n if (error.message && error.message.indexOf(\"9999\") > 0 && this._reconnect_counter <= 3) {\n return this.newReconnect().then(() => {\n return this.handleKlapRequest(payload).then((result) => {\n return result ? true : false;\n });\n });\n }\n this._reconnect_counter = 0;\n return false;\n });\n }\n }\n\n protected handleRequest(payload: string): Promise<any> {\n const URL = \"http://\" + this.ip + \"/app?token=\" + this.token;\n\n const headers = {\n Cookie: this.cookie,\n Connection: \"Keep-Alive\",\n };\n\n if (this.tpLinkCipher) {\n const encryptedPayload = this.tpLinkCipher.encrypt(payload);\n\n const securePassthroughPayload = {\n method: \"securePassthrough\",\n params: {\n request: encryptedPayload,\n },\n };\n\n const config = {\n headers: headers,\n timeout: this._timeout * 1000,\n };\n\n return this._axios\n .post(URL, securePassthroughPayload, config)\n .then((res: AxiosResponse) => {\n if (res.data.error_code) {\n if (res.data.error_code === \"9999\" || (res.data.error_code === 9999 && this._reconnect_counter <= 3)) {\n //@ts-ignore\n this.log.error(\" Error Code: \" + res.data.error_code + \", \" + this.ERROR_CODES[res.data.error_code]);\n this.log.debug(\"Trying to reconnect...\");\n return this.reconnect().then(() => {\n return this.getDeviceInfo();\n });\n }\n this._reconnect_counter = 0;\n return this.handleError(res.data.error_code, \"357\");\n }\n\n const decryptedResponse = this.tpLinkCipher.decrypt(res.data.result.response);\n try {\n const response = JSON.parse(decryptedResponse);\n this.log.debug(response);\n if (response.error_code !== 0) {\n return this.handleError(response.error_code, \"364\");\n }\n return response;\n } catch (error) {\n return this.handleError(JSON.parse(decryptedResponse).error_code, \"368\");\n }\n })\n .catch((error: Error) => {\n return this.handleError(error.message, \"656\");\n });\n }\n return new Promise<true>((resolve, reject) => {\n reject();\n });\n }\n\n protected handleKlapRequest(payload: string): Promise<any> {\n if (this.newTpLinkCipher) {\n const data = this.newTpLinkCipher.encrypt(payload);\n\n return this.raw_request(\"request\", data.encryptedPayload, \"arraybuffer\", { seq: data.seq.toString() })\n .then((res) => {\n return JSON.parse(this.newTpLinkCipher.decrypt(res));\n })\n .catch((error: Error) => {\n return this.handleError(error.message, \"671\");\n });\n }\n return new Promise<true>((resolve, reject) => {\n reject();\n });\n }\n\n protected async reconnect(): Promise<void> {\n this._reconnect_counter++;\n return this.handshake().then(() => {\n this.login().then(() => {\n return;\n });\n });\n }\n\n protected async newReconnect(): Promise<void> {\n this._reconnect_counter++;\n return this.handshake_new().then(() => {\n return;\n });\n }\n\n private reAuthenticate(): void {\n this.log.debug(\"Reauthenticating\");\n if (this.is_klap) {\n this.handshake_new()\n .then(() => {\n this.log.info(\"KLAP Authenticated successfully\");\n })\n .catch(() => {\n this.log.error(\"KLAP Handshake New failed\");\n this.is_klap = false;\n });\n } else {\n this.handshake().then(() => {\n this.login()\n .then(() => {\n this.log.info(\"Authenticated successfully\");\n })\n .catch(() => {\n this.log.error(\"Login failed\");\n });\n });\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_axios", "crypto", "axios", "utf8", "uuidv4", "TpLinkCipher", "http", "NewTpLinkCipher", "URL", "headers"]
|
|
7
7
|
}
|
package/io-package.json
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "tapo",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.4",
|
|
5
5
|
"news": {
|
|
6
|
-
"0.4.
|
|
6
|
+
"0.4.4": {
|
|
7
|
+
"en": "improve handshake if e-mail is not entered in lowercase",
|
|
8
|
+
"de": "Handshake verbessern, wenn E-Mail nicht in Kleinbuchstaben eingegeben wird",
|
|
9
|
+
"ru": "улучшить рукопожатие, если электронная почта не вводится в нижнюю очередь",
|
|
10
|
+
"pt": "melhorar o aperto de mão se o e-mail não for inserido em minúsculas",
|
|
11
|
+
"nl": "de handdruk verbeteren als e-mail niet in kleine letters wordt ingevoerd",
|
|
12
|
+
"fr": "améliorer la poignée de main si l'e-mail n'est pas entré en minuscule",
|
|
13
|
+
"it": "migliorare la stretta di mano se la posta elettronica non è inserita in minuscolo",
|
|
14
|
+
"es": "mejorar el apretón de manos si el e-mail no se introduce en el maletín",
|
|
15
|
+
"pl": "poprawić uścisk dłoni, jeśli e- mail nie jest wprowadzany w małych przypadkach",
|
|
16
|
+
"uk": "покращуйте руки, якщо e-mail не вводиться в нижній край",
|
|
17
|
+
"zh-cn": "如果电子邮件没有在小写中输入, 则改善握手方式"
|
|
18
|
+
},
|
|
19
|
+
"0.4.3": {
|
|
7
20
|
"en": "fix handshake for device with HW v1.20",
|
|
8
|
-
"de": "handshake für Gerät mit HW v1.20",
|
|
21
|
+
"de": "Fix für handshake für Gerät mit HW v1.20",
|
|
9
22
|
"ru": "исправить рукопожатие для устройства с HW v1.20",
|
|
10
23
|
"pt": "corrigir aperto de mão para dispositivo com HW v1.20",
|
|
11
24
|
"nl": "fix handshake voor apparaat met HW v1.20",
|
|
@@ -15,84 +28,6 @@
|
|
|
15
28
|
"pl": "naprawić uścisk dłoni dla urządzenia z HW v1.20",
|
|
16
29
|
"uk": "закріпити запіканка для пристрою з HW v1.20",
|
|
17
30
|
"zh-cn": "以 HW v1. 20 为设备固定握手方式"
|
|
18
|
-
},
|
|
19
|
-
"0.4.2-beta.8": {
|
|
20
|
-
"en": "improve handshake for old devices",
|
|
21
|
-
"de": "handshake für alte geräte verbessern",
|
|
22
|
-
"ru": "улучшить рукопожатие для старых устройств",
|
|
23
|
-
"pt": "melhorar o aperto de mão para dispositivos antigos",
|
|
24
|
-
"nl": "verbetering van de handdruk voor oude apparaten",
|
|
25
|
-
"fr": "améliorer la poignée de main pour les anciens appareils",
|
|
26
|
-
"it": "migliorare la stretta di mano per i vecchi dispositivi",
|
|
27
|
-
"es": "mejorar el apretón de manos para dispositivos antiguos",
|
|
28
|
-
"pl": "poprawić uścisk dłoni dla starych urządzeń",
|
|
29
|
-
"uk": "поліпшити хек для старих пристроїв",
|
|
30
|
-
"zh-cn": "改进旧设备的握手方式"
|
|
31
|
-
},
|
|
32
|
-
"0.4.2-beta.7": {
|
|
33
|
-
"en": "improve handshake for old devices",
|
|
34
|
-
"de": "handshake für alte geräte verbessern",
|
|
35
|
-
"ru": "улучшить рукопожатие для старых устройств",
|
|
36
|
-
"pt": "melhorar o aperto de mão para dispositivos antigos",
|
|
37
|
-
"nl": "verbetering van de handdruk voor oude apparaten",
|
|
38
|
-
"fr": "améliorer la poignée de main pour les anciens appareils",
|
|
39
|
-
"it": "migliorare la stretta di mano per i vecchi dispositivi",
|
|
40
|
-
"es": "mejorar el apretón de manos para dispositivos antiguos",
|
|
41
|
-
"pl": "poprawić uścisk dłoni dla starych urządzeń",
|
|
42
|
-
"uk": "поліпшити хек для старих пристроїв",
|
|
43
|
-
"zh-cn": "改进旧设备的握手方式"
|
|
44
|
-
},
|
|
45
|
-
"0.4.2-beta.6": {
|
|
46
|
-
"en": "improve handshake for old devices",
|
|
47
|
-
"de": "handshake für alte geräte verbessern",
|
|
48
|
-
"ru": "улучшить рукопожатие для старых устройств",
|
|
49
|
-
"pt": "melhorar o aperto de mão para dispositivos antigos",
|
|
50
|
-
"nl": "verbetering van de handdruk voor oude apparaten",
|
|
51
|
-
"fr": "améliorer la poignée de main pour les anciens appareils",
|
|
52
|
-
"it": "migliorare la stretta di mano per i vecchi dispositivi",
|
|
53
|
-
"es": "mejorar el apretón de manos para dispositivos antiguos",
|
|
54
|
-
"pl": "poprawić uścisk dłoni dla starych urządzeń",
|
|
55
|
-
"uk": "поліпшити хек для старих пристроїв",
|
|
56
|
-
"zh-cn": "改进旧设备的握手方式"
|
|
57
|
-
},
|
|
58
|
-
"0.4.2-beta.5": {
|
|
59
|
-
"en": "improve handshake for old devices",
|
|
60
|
-
"de": "handshake für alte geräte verbessern",
|
|
61
|
-
"ru": "улучшить рукопожатие для старых устройств",
|
|
62
|
-
"pt": "melhorar o aperto de mão para dispositivos antigos",
|
|
63
|
-
"nl": "verbetering van de handdruk voor oude apparaten",
|
|
64
|
-
"fr": "améliorer la poignée de main pour les anciens appareils",
|
|
65
|
-
"it": "migliorare la stretta di mano per i vecchi dispositivi",
|
|
66
|
-
"es": "mejorar el apretón de manos para dispositivos antiguos",
|
|
67
|
-
"pl": "poprawić uścisk dłoni dla starych urządzeń",
|
|
68
|
-
"uk": "поліпшити хек для старих пристроїв",
|
|
69
|
-
"zh-cn": "改进旧设备的握手方式"
|
|
70
|
-
},
|
|
71
|
-
"0.4.2-beta.4": {
|
|
72
|
-
"en": "improve handshake for old devices",
|
|
73
|
-
"de": "handshake für alte geräte verbessern",
|
|
74
|
-
"ru": "улучшить рукопожатие для старых устройств",
|
|
75
|
-
"pt": "melhorar o aperto de mão para dispositivos antigos",
|
|
76
|
-
"nl": "verbetering van de handdruk voor oude apparaten",
|
|
77
|
-
"fr": "améliorer la poignée de main pour les anciens appareils",
|
|
78
|
-
"it": "migliorare la stretta di mano per i vecchi dispositivi",
|
|
79
|
-
"es": "mejorar el apretón de manos para dispositivos antiguos",
|
|
80
|
-
"pl": "poprawić uścisk dłoni dla starych urządzeń",
|
|
81
|
-
"uk": "поліпшити хек для старих пристроїв",
|
|
82
|
-
"zh-cn": "改进旧设备的握手方式"
|
|
83
|
-
},
|
|
84
|
-
"0.4.2-beta.3": {
|
|
85
|
-
"en": "improve handshake for old devices",
|
|
86
|
-
"de": "handshake für alte geräte verbessern",
|
|
87
|
-
"ru": "улучшить рукопожатие для старых устройств",
|
|
88
|
-
"pt": "melhorar o aperto de mão para dispositivos antigos",
|
|
89
|
-
"nl": "verbetering van de handdruk voor oude apparaten",
|
|
90
|
-
"fr": "améliorer la poignée de main pour les anciens appareils",
|
|
91
|
-
"it": "migliorare la stretta di mano per i vecchi dispositivi",
|
|
92
|
-
"es": "mejorar el apretón de manos para dispositivos antiguos",
|
|
93
|
-
"pl": "poprawić uścisk dłoni dla starych urządzeń",
|
|
94
|
-
"uk": "поліпшити хек для старих пристроїв",
|
|
95
|
-
"zh-cn": "改进旧设备的握手方式"
|
|
96
31
|
}
|
|
97
32
|
},
|
|
98
33
|
"titleLang": {
|
|
@@ -119,13 +54,8 @@
|
|
|
119
54
|
"pl": "Adapter do TP-Link Tapo",
|
|
120
55
|
"zh-cn": "TP-Link Tapo 适配器"
|
|
121
56
|
},
|
|
122
|
-
"authors": [
|
|
123
|
-
|
|
124
|
-
],
|
|
125
|
-
"keywords": [
|
|
126
|
-
"tp-link",
|
|
127
|
-
"tapo"
|
|
128
|
-
],
|
|
57
|
+
"authors": ["TA2k <tombox2020@gmail.com>"],
|
|
58
|
+
"keywords": ["tp-link", "tapo"],
|
|
129
59
|
"license": "MIT",
|
|
130
60
|
"platform": "Javascript/Node.js",
|
|
131
61
|
"main": "build/main.js",
|
|
@@ -159,12 +89,8 @@
|
|
|
159
89
|
}
|
|
160
90
|
]
|
|
161
91
|
},
|
|
162
|
-
"encryptedNative": [
|
|
163
|
-
|
|
164
|
-
],
|
|
165
|
-
"protectedNative": [
|
|
166
|
-
"password"
|
|
167
|
-
],
|
|
92
|
+
"encryptedNative": ["password"],
|
|
93
|
+
"protectedNative": ["password"],
|
|
168
94
|
"native": {
|
|
169
95
|
"username": "",
|
|
170
96
|
"password": "",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.tapo",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Adapter for TP-Link Tapo",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TA2k",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
24
24
|
"@iobroker/adapter-core": "^3.2.3",
|
|
25
25
|
"@iobroker/testing": "^5.0.0",
|
|
26
|
-
"axios": "^
|
|
26
|
+
"axios": "^1.7.9",
|
|
27
27
|
"json-bigint": "^1.0.0",
|
|
28
28
|
"json2iob": "^2.6.12",
|
|
29
29
|
"node-fetch": "^2.7.0",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"@types/proxyquire": "^1.3.31",
|
|
44
44
|
"@types/utf8": "^3.0.3",
|
|
45
45
|
"@types/uuid": "^10.0.0",
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
47
|
-
"@typescript-eslint/parser": "^8.
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^8.18.0",
|
|
47
|
+
"@typescript-eslint/parser": "^8.18.0",
|
|
48
48
|
"eslint": "^9.16.0",
|
|
49
49
|
"eslint-config-prettier": "^9.1.0",
|
|
50
50
|
"eslint-plugin-prettier": "^5.2.1",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"source-map-support": "^0.5.21",
|
|
55
55
|
"ts-node": "^10.9.2",
|
|
56
56
|
"typescript": "~5.7.2",
|
|
57
|
-
"typescript-eslint": "^8.
|
|
57
|
+
"typescript-eslint": "^8.18.0"
|
|
58
58
|
},
|
|
59
59
|
"main": "build/main.js",
|
|
60
60
|
"files": [
|