eufy-security-client 2.4.2 → 2.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.
Files changed (87) hide show
  1. package/README.md +12 -0
  2. package/build/error.d.ts +57 -57
  3. package/build/error.js +155 -155
  4. package/build/eufysecurity.d.ts +162 -161
  5. package/build/eufysecurity.js +2104 -2091
  6. package/build/eufysecurity.js.map +1 -1
  7. package/build/http/api.d.ts +90 -90
  8. package/build/http/api.js +1407 -1407
  9. package/build/http/api.js.map +1 -1
  10. package/build/http/cache.d.ts +8 -8
  11. package/build/http/cache.js +33 -33
  12. package/build/http/const.d.ts +3 -3
  13. package/build/http/const.js +8545 -8545
  14. package/build/http/device.d.ts +360 -360
  15. package/build/http/device.js +2793 -2793
  16. package/build/http/device.js.map +1 -1
  17. package/build/http/error.d.ts +28 -28
  18. package/build/http/error.js +76 -76
  19. package/build/http/index.d.ts +10 -10
  20. package/build/http/index.js +29 -29
  21. package/build/http/interfaces.d.ts +202 -202
  22. package/build/http/interfaces.js +2 -2
  23. package/build/http/models.d.ts +561 -561
  24. package/build/http/models.js +2 -2
  25. package/build/http/parameter.d.ts +5 -5
  26. package/build/http/parameter.js +75 -75
  27. package/build/http/station.d.ts +292 -292
  28. package/build/http/station.js +6780 -6780
  29. package/build/http/station.js.map +1 -1
  30. package/build/http/types.d.ts +945 -945
  31. package/build/http/types.js +6070 -6070
  32. package/build/http/utils.d.ts +37 -37
  33. package/build/http/utils.js +370 -370
  34. package/build/index.d.ts +7 -7
  35. package/build/index.js +25 -25
  36. package/build/interfaces.d.ts +113 -113
  37. package/build/interfaces.js +2 -2
  38. package/build/mqtt/interface.d.ts +6 -6
  39. package/build/mqtt/interface.js +2 -2
  40. package/build/mqtt/model.d.ts +24 -24
  41. package/build/mqtt/model.js +2 -2
  42. package/build/mqtt/service.d.ts +30 -30
  43. package/build/mqtt/service.js +168 -168
  44. package/build/mqtt/service.js.map +1 -1
  45. package/build/p2p/ble.d.ts +47 -47
  46. package/build/p2p/ble.js +188 -188
  47. package/build/p2p/ble.js.map +1 -1
  48. package/build/p2p/error.d.ts +24 -24
  49. package/build/p2p/error.js +67 -67
  50. package/build/p2p/index.d.ts +8 -8
  51. package/build/p2p/index.js +27 -27
  52. package/build/p2p/interfaces.d.ts +162 -162
  53. package/build/p2p/interfaces.js +2 -2
  54. package/build/p2p/models.d.ts +146 -146
  55. package/build/p2p/models.js +2 -2
  56. package/build/p2p/session.d.ts +168 -168
  57. package/build/p2p/session.js +2087 -2087
  58. package/build/p2p/session.js.map +1 -1
  59. package/build/p2p/talkback.d.ts +10 -10
  60. package/build/p2p/talkback.js +22 -22
  61. package/build/p2p/types.d.ts +923 -923
  62. package/build/p2p/types.js +957 -957
  63. package/build/p2p/utils.d.ts +56 -56
  64. package/build/p2p/utils.js +653 -653
  65. package/build/push/client.d.ts +51 -51
  66. package/build/push/client.js +311 -311
  67. package/build/push/client.js.map +1 -1
  68. package/build/push/index.d.ts +5 -5
  69. package/build/push/index.js +24 -24
  70. package/build/push/interfaces.d.ts +19 -19
  71. package/build/push/interfaces.js +2 -2
  72. package/build/push/models.d.ts +292 -292
  73. package/build/push/models.js +30 -30
  74. package/build/push/parser.d.ts +28 -28
  75. package/build/push/parser.js +215 -215
  76. package/build/push/parser.js.map +1 -1
  77. package/build/push/service.d.ts +45 -45
  78. package/build/push/service.js +643 -643
  79. package/build/push/service.js.map +1 -1
  80. package/build/push/types.d.ts +176 -176
  81. package/build/push/types.js +192 -192
  82. package/build/push/utils.d.ts +7 -7
  83. package/build/push/utils.js +102 -102
  84. package/build/utils.d.ts +16 -13
  85. package/build/utils.js +207 -191
  86. package/build/utils.js.map +1 -1
  87. package/package.json +10 -10
@@ -1,644 +1,644 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.PushNotificationService = void 0;
30
- const got_1 = __importDefault(require("got"));
31
- const qs = __importStar(require("qs"));
32
- const ts_log_1 = require("ts-log");
33
- const tiny_typed_emitter_1 = require("tiny-typed-emitter");
34
- const utils_1 = require("./utils");
35
- const client_1 = require("./client");
36
- const device_1 = require("../http/device");
37
- const types_1 = require("../http/types");
38
- const utils_2 = require("../http/utils");
39
- const utils_3 = require("../utils");
40
- class PushNotificationService extends tiny_typed_emitter_1.TypedEmitter {
41
- constructor(log = ts_log_1.dummyLogger) {
42
- super();
43
- this.APP_PACKAGE = "com.oceanwing.battery.cam";
44
- this.APP_ID = "1:348804314802:android:440a6773b3620da7";
45
- this.APP_SENDER_ID = "348804314802";
46
- this.APP_CERT_SHA1 = "F051262F9F99B638F3C76DE349830638555B4A0A";
47
- this.FCM_PROJECT_ID = "batterycam-3250a";
48
- this.GOOGLE_API_KEY = "AIzaSyCSz1uxGrHXsEktm7O3_wv-uLGpC9BvXR8";
49
- this.AUTH_VERSION = "FIS_v2";
50
- this.retryDelay = 0;
51
- this.persistentIds = [];
52
- this.connected = false;
53
- this.connecting = false;
54
- this.log = log;
55
- }
56
- buildExpiresAt(expiresIn) {
57
- if (expiresIn.endsWith("ms")) {
58
- return new Date().getTime() + Number.parseInt(expiresIn.substring(0, expiresIn.length - 2));
59
- }
60
- else if (expiresIn.endsWith("s")) {
61
- return new Date().getTime() + Number.parseInt(expiresIn.substring(0, expiresIn.length - 1)) * 1000;
62
- }
63
- throw new Error(`Unknown expiresIn-format: ${expiresIn}`);
64
- }
65
- async registerFid(fid) {
66
- const url = `https://firebaseinstallations.googleapis.com/v1/projects/${this.FCM_PROJECT_ID}/installations`;
67
- try {
68
- const response = await (0, got_1.default)(url, {
69
- method: "post",
70
- json: {
71
- fid: fid,
72
- appId: `${this.APP_ID}`,
73
- authVersion: `${this.AUTH_VERSION}`,
74
- sdkVersion: "a:16.3.1",
75
- },
76
- headers: {
77
- "X-Android-Package": `${this.APP_PACKAGE}`,
78
- "X-Android-Cert": `${this.APP_CERT_SHA1}`,
79
- "x-goog-api-key": `${this.GOOGLE_API_KEY}`,
80
- },
81
- responseType: "json",
82
- http2: false,
83
- throwHttpErrors: false,
84
- retry: {
85
- limit: 3,
86
- methods: ["POST"]
87
- }
88
- }).catch(error => {
89
- this.log.error("registerFid - Error:", error);
90
- return error;
91
- });
92
- if (response.statusCode == 200) {
93
- const result = response.body;
94
- return {
95
- ...result,
96
- authToken: {
97
- ...result.authToken,
98
- expiresAt: this.buildExpiresAt(result.authToken.expiresIn),
99
- },
100
- };
101
- }
102
- else {
103
- this.log.error("registerFid - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
104
- throw new Error(`FID registration failed with error: ${response.statusMessage}`);
105
- }
106
- }
107
- catch (error) {
108
- this.log.error("registerFid - Generic Error:", error);
109
- throw new Error(`FID registration failed with error: ${error}`);
110
- }
111
- }
112
- async renewFidToken(fid, refreshToken) {
113
- const url = `https://firebaseinstallations.googleapis.com/v1/projects/${this.FCM_PROJECT_ID}/installations/${fid}/authTokens:generate`;
114
- try {
115
- const response = await (0, got_1.default)(url, {
116
- method: "post",
117
- json: {
118
- installation: {
119
- appId: `${this.APP_ID}`,
120
- sdkVersion: "a:16.3.1",
121
- }
122
- },
123
- headers: {
124
- "X-Android-Package": `${this.APP_PACKAGE}`,
125
- "X-Android-Cert": `${this.APP_CERT_SHA1}`,
126
- "x-goog-api-key": `${this.GOOGLE_API_KEY}`,
127
- Authorization: `${this.AUTH_VERSION} ${refreshToken}`
128
- },
129
- responseType: "json",
130
- http2: false,
131
- throwHttpErrors: false,
132
- retry: {
133
- limit: 3,
134
- methods: ["POST"]
135
- }
136
- }).catch(error => {
137
- this.log.error("renewFidToken - Error:", error);
138
- return error;
139
- });
140
- if (response.statusCode == 200) {
141
- const result = response.body;
142
- return {
143
- ...result,
144
- expiresAt: this.buildExpiresAt(result.expiresIn),
145
- };
146
- }
147
- else {
148
- this.log.error("renewFidToken - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
149
- throw new Error(`FID Token renewal failed with error: ${response.statusMessage}`);
150
- }
151
- }
152
- catch (error) {
153
- this.log.error("renewFidToken - Generic Error:", error);
154
- throw new Error(`FID Token renewal failed with error: ${error}`);
155
- }
156
- }
157
- async createPushCredentials() {
158
- const generatedFid = (0, utils_1.generateFid)();
159
- return await this.registerFid(generatedFid)
160
- .then(async (registerFidResponse) => {
161
- const checkinResponse = await this.executeCheckin();
162
- return {
163
- fidResponse: registerFidResponse,
164
- checkinResponse: checkinResponse
165
- };
166
- })
167
- .then(async (result) => {
168
- const registerGcmResponse = await this.registerGcm(result.fidResponse, result.checkinResponse);
169
- return {
170
- ...result,
171
- gcmResponse: registerGcmResponse,
172
- };
173
- }).catch((error) => {
174
- throw error;
175
- });
176
- }
177
- async renewPushCredentials(credentials) {
178
- return await this.renewFidToken(credentials.fidResponse.fid, credentials.fidResponse.refreshToken)
179
- .then(async (response) => {
180
- credentials.fidResponse.authToken = response;
181
- return await this.executeCheckin();
182
- })
183
- .then(async (response) => {
184
- const registerGcmResponse = await this.registerGcm(credentials.fidResponse, response);
185
- return {
186
- fidResponse: credentials.fidResponse,
187
- checkinResponse: response,
188
- gcmResponse: registerGcmResponse,
189
- };
190
- })
191
- .catch(() => {
192
- return this.createPushCredentials();
193
- });
194
- }
195
- async loginPushCredentials(credentials) {
196
- return await this.executeCheckin()
197
- .then(async (response) => {
198
- const registerGcmResponse = await this.registerGcm(credentials.fidResponse, response);
199
- return {
200
- fidResponse: credentials.fidResponse,
201
- checkinResponse: response,
202
- gcmResponse: registerGcmResponse,
203
- };
204
- })
205
- .catch(() => {
206
- return this.createPushCredentials();
207
- });
208
- }
209
- async executeCheckin() {
210
- const url = "https://android.clients.google.com/checkin";
211
- try {
212
- const buffer = await (0, utils_1.buildCheckinRequest)();
213
- const response = await (0, got_1.default)(url, {
214
- method: "post",
215
- body: Buffer.from(buffer),
216
- headers: {
217
- "Content-Type": "application/x-protobuf",
218
- },
219
- responseType: "buffer",
220
- http2: false,
221
- throwHttpErrors: false,
222
- retry: {
223
- limit: 3,
224
- methods: ["POST"]
225
- }
226
- }).catch(error => {
227
- this.log.error("executeCheckin - Error:", error);
228
- return error;
229
- });
230
- if (response.statusCode == 200) {
231
- return await (0, utils_1.parseCheckinResponse)(response.body);
232
- }
233
- else {
234
- this.log.error("executeCheckin - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
235
- throw new Error(`Google checkin failed with error: ${response.statusMessage}`);
236
- }
237
- }
238
- catch (error) {
239
- this.log.error("executeCheckin - Generic Error:", error);
240
- throw new Error(`Google checkin failed with error: ${error}`);
241
- }
242
- }
243
- async registerGcm(fidInstallationResponse, checkinResponse) {
244
- const url = "https://android.clients.google.com/c2dm/register3";
245
- const androidId = checkinResponse.androidId;
246
- const fid = fidInstallationResponse.fid;
247
- const securityToken = checkinResponse.securityToken;
248
- const retry = 5;
249
- try {
250
- for (let retry_count = 1; retry_count <= retry; retry_count++) {
251
- const response = await (0, got_1.default)(url, {
252
- method: "post",
253
- body: qs.stringify({
254
- "X-subtype": `${this.APP_SENDER_ID}`,
255
- sender: `${this.APP_SENDER_ID}`,
256
- "X-app_ver": "741",
257
- "X-osv": "25",
258
- "X-cliv": "fiid-20.2.0",
259
- "X-gmsv": "201216023",
260
- "X-appid": `${fid}`,
261
- "X-scope": "*",
262
- "X-Goog-Firebase-Installations-Auth": `${fidInstallationResponse.authToken.token}`,
263
- "X-gmp_app_id": `${this.APP_ID}`,
264
- "X-Firebase-Client": "fire-abt/17.1.1+fire-installations/16.3.1+fire-android/+fire-analytics/17.4.2+fire-iid/20.2.0+fire-rc/17.0.0+fire-fcm/20.2.0+fire-cls/17.0.0+fire-cls-ndk/17.0.0+fire-core/19.3.0",
265
- "X-firebase-app-name-hash": "R1dAH9Ui7M-ynoznwBdw01tLxhI",
266
- "X-Firebase-Client-Log-Type": "1",
267
- "X-app_ver_name": "v2.2.2_741",
268
- app: `${this.APP_PACKAGE}`,
269
- device: `${androidId}`,
270
- app_ver: "741",
271
- info: "g3EMJXXElLwaQEb1aBJ6XhxiHjPTUxc",
272
- gcm_ver: "201216023",
273
- plat: "0",
274
- cert: `${this.APP_CERT_SHA1}`,
275
- target_ver: "28",
276
- }),
277
- headers: {
278
- Authorization: `AidLogin ${androidId}:${securityToken}`,
279
- app: `${this.APP_PACKAGE}`,
280
- gcm_ver: "201216023",
281
- "User-Agent": "Android-GCM/1.5 (OnePlus5 NMF26X)",
282
- "content-type": "application/x-www-form-urlencoded",
283
- },
284
- http2: false,
285
- throwHttpErrors: false,
286
- retry: {
287
- limit: 3,
288
- methods: ["POST"]
289
- }
290
- }).catch(error => {
291
- this.log.error("registerGcm - Error:", error);
292
- return error;
293
- });
294
- if (response.statusCode == 200) {
295
- const result = response.body.split("=");
296
- if (result[0] == "Error") {
297
- this.log.debug("GCM register error, retry...", { retry: retry, retryCount: retry_count });
298
- if (retry_count == retry)
299
- throw new Error(`GCM-Register Error: ${result[1]}`);
300
- }
301
- else {
302
- return {
303
- token: result[1]
304
- };
305
- }
306
- }
307
- else {
308
- this.log.error("registerGcm - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
309
- throw new Error(`Google register to GCM failed with error: ${response.statusMessage}`);
310
- }
311
- await (0, utils_1.sleep)(10000 * retry_count);
312
- }
313
- throw new Error(`GCM-Register Error: Undefined!`);
314
- }
315
- catch (error) {
316
- this.log.error("registerGcm - Generic Error:", error);
317
- throw new Error(`Google register to GCM failed with error: ${error}`);
318
- }
319
- }
320
- _normalizePushMessage(message) {
321
- const normalized_message = {
322
- name: "",
323
- event_time: 0,
324
- type: -1,
325
- station_sn: "",
326
- device_sn: ""
327
- };
328
- if (message.payload.payload) {
329
- // CusPush
330
- normalized_message.type = Number.parseInt(message.payload.type);
331
- try {
332
- normalized_message.event_time = message.payload.event_time !== undefined ? (0, utils_1.convertTimestampMs)(Number.parseInt(message.payload.event_time)) : Number.parseInt(message.payload.event_time);
333
- }
334
- catch (error) {
335
- this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPush - event_time - Error:`, error);
336
- }
337
- normalized_message.station_sn = message.payload.station_sn;
338
- if (normalized_message.type === types_1.DeviceType.FLOODLIGHT)
339
- normalized_message.device_sn = message.payload.station_sn;
340
- else
341
- normalized_message.device_sn = message.payload.device_sn;
342
- if ((0, utils_3.isEmpty)(normalized_message.device_sn) && !(0, utils_3.isEmpty)(normalized_message.station_sn)) {
343
- normalized_message.device_sn = normalized_message.station_sn;
344
- }
345
- normalized_message.title = message.payload.title;
346
- normalized_message.content = message.payload.content;
347
- try {
348
- normalized_message.push_time = message.payload.push_time !== undefined ? (0, utils_1.convertTimestampMs)(Number.parseInt(message.payload.push_time)) : Number.parseInt(message.payload.push_time);
349
- }
350
- catch (error) {
351
- this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPush - push_time - Error:`, error);
352
- }
353
- if (normalized_message.station_sn.startsWith("T8030") || normalized_message.type === types_1.DeviceType.HB3) {
354
- const push_data = message.payload.payload;
355
- normalized_message.name = push_data.name ? push_data.name : "";
356
- normalized_message.channel = push_data.channel !== undefined ? push_data.channel : 0;
357
- normalized_message.cipher = push_data.cipher !== undefined ? push_data.cipher : 0;
358
- normalized_message.event_session = push_data.session_id !== undefined ? push_data.session_id : "";
359
- normalized_message.event_type = push_data.a !== undefined ? push_data.a : push_data.event_type;
360
- normalized_message.file_path = push_data.file_path !== undefined ? push_data.file_path : "";
361
- normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
362
- normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
363
- normalized_message.notification_style = push_data.notification_style;
364
- normalized_message.storage_type = push_data.storage_type !== undefined ? push_data.storage_type : 1;
365
- normalized_message.msg_type = push_data.msg_type;
366
- normalized_message.person_name = push_data.nick_name;
367
- normalized_message.person_id = push_data.person_id;
368
- normalized_message.tfcard_status = push_data.tfcard_status;
369
- normalized_message.user_type = push_data.user;
370
- normalized_message.user_name = push_data.user_name;
371
- normalized_message.station_guard_mode = push_data.arming;
372
- normalized_message.station_current_mode = push_data.mode;
373
- normalized_message.alarm_delay = push_data.alarm_delay;
374
- normalized_message.sound_alarm = push_data.alarm !== undefined ? push_data.alarm === 1 ? true : false : undefined;
375
- }
376
- else {
377
- if (device_1.Device.isBatteryDoorbell(normalized_message.type) || device_1.Device.isWiredDoorbellDual(normalized_message.type)) {
378
- const push_data = message.payload.payload;
379
- normalized_message.name = push_data.name ? push_data.name : "";
380
- //Get family face names from Doorbell Dual "Family Recognition" event
381
- if (push_data.objects !== undefined) {
382
- normalized_message.person_name = push_data.objects.names !== undefined ? push_data.objects.names.join(",") : "";
383
- }
384
- normalized_message.channel = push_data.channel !== undefined ? push_data.channel : 0;
385
- normalized_message.cipher = push_data.cipher !== undefined ? push_data.cipher : 0;
386
- normalized_message.event_session = push_data.session_id !== undefined ? push_data.session_id : "";
387
- normalized_message.event_type = push_data.event_type;
388
- normalized_message.file_path = push_data.file_path !== undefined && push_data.file_path !== "" && push_data.channel !== undefined ? (0, utils_2.getAbsoluteFilePath)(normalized_message.type, push_data.channel, push_data.file_path) : "";
389
- normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
390
- normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
391
- normalized_message.notification_style = push_data.notification_style;
392
- }
393
- else if (device_1.Device.isIndoorCamera(normalized_message.type) ||
394
- device_1.Device.isSoloCameras(normalized_message.type) ||
395
- device_1.Device.isFloodLightT8420X(normalized_message.type, normalized_message.device_sn) ||
396
- (device_1.Device.isFloodLight(normalized_message.type) && normalized_message.type !== types_1.DeviceType.FLOODLIGHT)) {
397
- const push_data = message.payload.payload;
398
- normalized_message.name = push_data.name ? push_data.name : "";
399
- normalized_message.channel = push_data.channel;
400
- normalized_message.cipher = push_data.cipher;
401
- normalized_message.event_session = push_data.session_id;
402
- normalized_message.event_type = push_data.event_type;
403
- //normalized_message.file_path = push_data.file_path !== undefined && push_data.file_path !== "" && push_data.channel !== undefined ? getAbsoluteFilePath(normalized_message.type, push_data.channel, push_data.file_path) : "";
404
- normalized_message.file_path = push_data.file_path;
405
- normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
406
- normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
407
- normalized_message.notification_style = push_data.notification_style;
408
- normalized_message.msg_type = push_data.msg_type;
409
- normalized_message.timeout = push_data.timeout;
410
- normalized_message.tfcard_status = push_data.tfcard_status;
411
- normalized_message.storage_type = push_data.storage_type !== undefined ? push_data.storage_type : 1;
412
- normalized_message.unique_id = push_data.unique_id;
413
- }
414
- else if (device_1.Device.isSmartSafe(normalized_message.type)) {
415
- const push_data = message.payload.payload;
416
- normalized_message.event_type = push_data.event_type;
417
- normalized_message.event_value = push_data.event_value;
418
- /*
419
- event_value: {
420
- type: 3, 3/4
421
- action: 1,
422
- figure_id: 0,
423
- user_id: 0
424
- }
425
- */
426
- normalized_message.name = push_data.dev_name !== undefined ? push_data.dev_name : "";
427
- /*normalized_message.short_user_id = push_data.short_user_id !== undefined ? push_data.short_user_id : "";
428
- normalized_message.user_id = push_data.user_id !== undefined ? push_data.user_id : "";*/
429
- }
430
- else if (device_1.Device.isLock(normalized_message.type)) {
431
- const push_data = message.payload.payload;
432
- normalized_message.event_type = push_data.event_type;
433
- normalized_message.short_user_id = push_data.short_user_id !== undefined ? push_data.short_user_id : "";
434
- normalized_message.user_id = push_data.user_id !== undefined ? push_data.user_id : "";
435
- normalized_message.name = push_data.device_name !== undefined ? push_data.device_name : "";
436
- }
437
- else {
438
- const push_data = message.payload.payload;
439
- normalized_message.name = push_data.device_name && push_data.device_name !== null && push_data.device_name !== "" ? push_data.device_name : push_data.n ? push_data.n : "";
440
- normalized_message.channel = push_data.c;
441
- normalized_message.cipher = push_data.k;
442
- normalized_message.event_session = push_data.session_id;
443
- normalized_message.event_type = push_data.a;
444
- normalized_message.file_path = push_data.c !== undefined && push_data.p !== undefined && push_data.p !== "" ? (0, utils_2.getAbsoluteFilePath)(normalized_message.type, push_data.c, push_data.p) : "";
445
- normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
446
- normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
447
- normalized_message.notification_style = push_data.notification_style;
448
- normalized_message.tfcard_status = push_data.tfcard;
449
- normalized_message.alarm_delay_type = push_data.alarm_type;
450
- normalized_message.alarm_delay = push_data.alarm_delay;
451
- normalized_message.alarm_type = push_data.type;
452
- normalized_message.sound_alarm = push_data.alarm !== undefined ? push_data.alarm === 1 ? true : false : undefined;
453
- normalized_message.user_name = push_data.user_name;
454
- normalized_message.user_type = push_data.user;
455
- normalized_message.user_id = push_data.user_id;
456
- normalized_message.short_user_id = push_data.short_user_id;
457
- normalized_message.station_guard_mode = push_data.arming;
458
- normalized_message.station_current_mode = push_data.mode;
459
- normalized_message.person_name = push_data.f;
460
- normalized_message.sensor_open = push_data.e !== undefined ? push_data.e === "1" ? true : false : undefined;
461
- normalized_message.device_online = push_data.m !== undefined ? push_data.m === 1 ? true : false : undefined;
462
- try {
463
- normalized_message.fetch_id = push_data.i !== undefined ? Number.parseInt(push_data.i) : undefined;
464
- }
465
- catch (error) {
466
- this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPushData - fetch_id - Error:`, error);
467
- }
468
- normalized_message.sense_id = push_data.j;
469
- normalized_message.battery_powered = push_data.batt_powered !== undefined ? push_data.batt_powered === 1 ? true : false : undefined;
470
- try {
471
- normalized_message.battery_low = push_data.bat_low !== undefined ? Number.parseInt(push_data.bat_low) : undefined;
472
- }
473
- catch (error) {
474
- this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPushData - battery_low - Error:`, error);
475
- }
476
- normalized_message.storage_type = push_data.storage_type !== undefined ? push_data.storage_type : 1;
477
- normalized_message.unique_id = push_data.unique_id;
478
- normalized_message.automation_id = push_data.automation_id;
479
- normalized_message.click_action = push_data.click_action;
480
- normalized_message.news_id = push_data.news_id;
481
- }
482
- }
483
- }
484
- else if (message.payload.doorbell !== undefined) {
485
- const push_data = (0, utils_3.parseJSON)(message.payload.doorbell, this.log);
486
- if (push_data !== undefined) {
487
- normalized_message.name = "Doorbell";
488
- normalized_message.type = 5;
489
- normalized_message.event_time = push_data.create_time !== undefined ? (0, utils_1.convertTimestampMs)(push_data.create_time) : push_data.create_time;
490
- normalized_message.station_sn = push_data.device_sn;
491
- normalized_message.device_sn = push_data.device_sn;
492
- normalized_message.title = push_data.title;
493
- normalized_message.content = push_data.content;
494
- normalized_message.push_time = push_data.event_time !== undefined ? (0, utils_1.convertTimestampMs)(push_data.event_time) : push_data.event_time;
495
- normalized_message.channel = push_data.channel;
496
- normalized_message.cipher = push_data.cipher;
497
- normalized_message.event_session = push_data.event_session;
498
- normalized_message.event_type = push_data.event_type;
499
- normalized_message.file_path = push_data.file_path;
500
- normalized_message.pic_url = push_data.pic_url;
501
- normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
502
- normalized_message.doorbell_url = push_data.url;
503
- normalized_message.doorbell_url_ex = push_data.url_ex;
504
- normalized_message.doorbell_video_url = push_data.video_url;
505
- }
506
- }
507
- return normalized_message;
508
- }
509
- onMessage(message) {
510
- this.log.debug("Raw push message received", message);
511
- this.emit("raw message", message);
512
- const normalized_message = this._normalizePushMessage(message);
513
- this.log.debug("Normalized push message received", normalized_message);
514
- this.emit("message", normalized_message);
515
- }
516
- getCurrentPushRetryDelay() {
517
- const delay = this.retryDelay == 0 ? 5000 : this.retryDelay;
518
- if (this.retryDelay < 60000)
519
- this.retryDelay += 10000;
520
- if (this.retryDelay >= 60000 && this.retryDelay < 600000)
521
- this.retryDelay += 60000;
522
- return delay;
523
- }
524
- setCredentials(credentials) {
525
- this.credentials = credentials;
526
- }
527
- getCredentials() {
528
- return this.credentials;
529
- }
530
- setPersistentIds(persistentIds) {
531
- this.persistentIds = persistentIds;
532
- }
533
- getPersistentIds() {
534
- return this.persistentIds;
535
- }
536
- async _open(renew = false) {
537
- if (!this.credentials || Object.keys(this.credentials).length === 0 || (this.credentials && this.credentials.fidResponse && new Date().getTime() >= this.credentials.fidResponse.authToken.expiresAt)) {
538
- this.log.debug(`Create new push credentials...`);
539
- this.credentials = await this.createPushCredentials().catch(error => {
540
- this.log.error("Create push credentials Error:", error);
541
- return undefined;
542
- });
543
- }
544
- else if (this.credentials && renew) {
545
- this.log.debug(`Renew push credentials...`);
546
- this.credentials = await this.renewPushCredentials(this.credentials).catch(error => {
547
- this.log.error("Push credentials renew Error:", error);
548
- return undefined;
549
- });
550
- }
551
- else {
552
- this.log.debug(`Login with previous push credentials...`, this.credentials);
553
- this.credentials = await this.loginPushCredentials(this.credentials).catch(error => {
554
- this.log.error("Push credentials login Error:", error);
555
- return undefined;
556
- });
557
- }
558
- if (this.credentials) {
559
- this.emit("credential", this.credentials);
560
- this.clearCredentialsTimeout();
561
- this.credentialsTimeout = setTimeout(async () => {
562
- this.log.info("Push notification token is expiring, renew it.");
563
- await this._open(true);
564
- }, this.credentials.fidResponse.authToken.expiresAt - new Date().getTime() - 60000);
565
- if (this.pushClient) {
566
- this.pushClient.removeAllListeners();
567
- }
568
- this.pushClient = await client_1.PushClient.init({
569
- androidId: this.credentials.checkinResponse.androidId,
570
- securityToken: this.credentials.checkinResponse.securityToken,
571
- }, this.log);
572
- if (this.persistentIds)
573
- this.pushClient.setPersistentIds(this.persistentIds);
574
- const token = this.credentials.gcmResponse.token;
575
- this.pushClient.on("connect", () => {
576
- this.emit("connect", token);
577
- this.connected = true;
578
- this.connecting = false;
579
- });
580
- this.pushClient.on("close", () => {
581
- this.emit("close");
582
- this.connected = false;
583
- this.connecting = false;
584
- });
585
- this.pushClient.on("message", (msg) => this.onMessage(msg));
586
- this.pushClient.connect();
587
- }
588
- else {
589
- this.emit("close");
590
- this.connected = false;
591
- this.connecting = false;
592
- this.log.error("Push notifications are disabled, because the registration failed!");
593
- }
594
- }
595
- async open() {
596
- if (!this.connecting && !this.connected) {
597
- this.connecting = true;
598
- await this._open().catch((error) => {
599
- this.log.error(`Got exception trying to initialize push notifications`, error);
600
- });
601
- if (!this.credentials) {
602
- this.clearRetryTimeout();
603
- const delay = this.getCurrentPushRetryDelay();
604
- this.log.info(`Retry to register/login for push notification in ${delay / 1000} seconds...`);
605
- this.retryTimeout = setTimeout(async () => {
606
- this.log.info(`Retry to register/login for push notification`);
607
- await this.open();
608
- }, delay);
609
- }
610
- else {
611
- this.resetRetryTimeout();
612
- this.emit("credential", this.credentials);
613
- }
614
- }
615
- return this.credentials;
616
- }
617
- close() {
618
- var _a;
619
- this.resetRetryTimeout();
620
- this.clearCredentialsTimeout();
621
- (_a = this.pushClient) === null || _a === void 0 ? void 0 : _a.close();
622
- }
623
- clearCredentialsTimeout() {
624
- if (this.credentialsTimeout) {
625
- clearTimeout(this.credentialsTimeout);
626
- this.credentialsTimeout = undefined;
627
- }
628
- }
629
- clearRetryTimeout() {
630
- if (this.retryTimeout) {
631
- clearTimeout(this.retryTimeout);
632
- this.retryTimeout = undefined;
633
- }
634
- }
635
- resetRetryTimeout() {
636
- this.clearRetryTimeout();
637
- this.retryDelay = 0;
638
- }
639
- isConnected() {
640
- return this.connected;
641
- }
642
- }
643
- exports.PushNotificationService = PushNotificationService;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.PushNotificationService = void 0;
30
+ const got_1 = __importDefault(require("got"));
31
+ const qs = __importStar(require("qs"));
32
+ const ts_log_1 = require("ts-log");
33
+ const tiny_typed_emitter_1 = require("tiny-typed-emitter");
34
+ const utils_1 = require("./utils");
35
+ const client_1 = require("./client");
36
+ const device_1 = require("../http/device");
37
+ const types_1 = require("../http/types");
38
+ const utils_2 = require("../http/utils");
39
+ const utils_3 = require("../utils");
40
+ class PushNotificationService extends tiny_typed_emitter_1.TypedEmitter {
41
+ constructor(log = ts_log_1.dummyLogger) {
42
+ super();
43
+ this.APP_PACKAGE = "com.oceanwing.battery.cam";
44
+ this.APP_ID = "1:348804314802:android:440a6773b3620da7";
45
+ this.APP_SENDER_ID = "348804314802";
46
+ this.APP_CERT_SHA1 = "F051262F9F99B638F3C76DE349830638555B4A0A";
47
+ this.FCM_PROJECT_ID = "batterycam-3250a";
48
+ this.GOOGLE_API_KEY = "AIzaSyCSz1uxGrHXsEktm7O3_wv-uLGpC9BvXR8";
49
+ this.AUTH_VERSION = "FIS_v2";
50
+ this.retryDelay = 0;
51
+ this.persistentIds = [];
52
+ this.connected = false;
53
+ this.connecting = false;
54
+ this.log = log;
55
+ }
56
+ buildExpiresAt(expiresIn) {
57
+ if (expiresIn.endsWith("ms")) {
58
+ return new Date().getTime() + Number.parseInt(expiresIn.substring(0, expiresIn.length - 2));
59
+ }
60
+ else if (expiresIn.endsWith("s")) {
61
+ return new Date().getTime() + Number.parseInt(expiresIn.substring(0, expiresIn.length - 1)) * 1000;
62
+ }
63
+ throw new Error(`Unknown expiresIn-format: ${expiresIn}`);
64
+ }
65
+ async registerFid(fid) {
66
+ const url = `https://firebaseinstallations.googleapis.com/v1/projects/${this.FCM_PROJECT_ID}/installations`;
67
+ try {
68
+ const response = await (0, got_1.default)(url, {
69
+ method: "post",
70
+ json: {
71
+ fid: fid,
72
+ appId: `${this.APP_ID}`,
73
+ authVersion: `${this.AUTH_VERSION}`,
74
+ sdkVersion: "a:16.3.1",
75
+ },
76
+ headers: {
77
+ "X-Android-Package": `${this.APP_PACKAGE}`,
78
+ "X-Android-Cert": `${this.APP_CERT_SHA1}`,
79
+ "x-goog-api-key": `${this.GOOGLE_API_KEY}`,
80
+ },
81
+ responseType: "json",
82
+ http2: false,
83
+ throwHttpErrors: false,
84
+ retry: {
85
+ limit: 3,
86
+ methods: ["POST"]
87
+ }
88
+ }).catch(error => {
89
+ this.log.error("registerFid - Error:", error);
90
+ return error;
91
+ });
92
+ if (response.statusCode == 200) {
93
+ const result = response.body;
94
+ return {
95
+ ...result,
96
+ authToken: {
97
+ ...result.authToken,
98
+ expiresAt: this.buildExpiresAt(result.authToken.expiresIn),
99
+ },
100
+ };
101
+ }
102
+ else {
103
+ this.log.error("registerFid - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
104
+ throw new Error(`FID registration failed with error: ${response.statusMessage}`);
105
+ }
106
+ }
107
+ catch (error) {
108
+ this.log.error("registerFid - Generic Error:", error);
109
+ throw new Error(`FID registration failed with error: ${error}`);
110
+ }
111
+ }
112
+ async renewFidToken(fid, refreshToken) {
113
+ const url = `https://firebaseinstallations.googleapis.com/v1/projects/${this.FCM_PROJECT_ID}/installations/${fid}/authTokens:generate`;
114
+ try {
115
+ const response = await (0, got_1.default)(url, {
116
+ method: "post",
117
+ json: {
118
+ installation: {
119
+ appId: `${this.APP_ID}`,
120
+ sdkVersion: "a:16.3.1",
121
+ }
122
+ },
123
+ headers: {
124
+ "X-Android-Package": `${this.APP_PACKAGE}`,
125
+ "X-Android-Cert": `${this.APP_CERT_SHA1}`,
126
+ "x-goog-api-key": `${this.GOOGLE_API_KEY}`,
127
+ Authorization: `${this.AUTH_VERSION} ${refreshToken}`
128
+ },
129
+ responseType: "json",
130
+ http2: false,
131
+ throwHttpErrors: false,
132
+ retry: {
133
+ limit: 3,
134
+ methods: ["POST"]
135
+ }
136
+ }).catch(error => {
137
+ this.log.error("renewFidToken - Error:", error);
138
+ return error;
139
+ });
140
+ if (response.statusCode == 200) {
141
+ const result = response.body;
142
+ return {
143
+ ...result,
144
+ expiresAt: this.buildExpiresAt(result.expiresIn),
145
+ };
146
+ }
147
+ else {
148
+ this.log.error("renewFidToken - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
149
+ throw new Error(`FID Token renewal failed with error: ${response.statusMessage}`);
150
+ }
151
+ }
152
+ catch (error) {
153
+ this.log.error("renewFidToken - Generic Error:", error);
154
+ throw new Error(`FID Token renewal failed with error: ${error}`);
155
+ }
156
+ }
157
+ async createPushCredentials() {
158
+ const generatedFid = (0, utils_1.generateFid)();
159
+ return await this.registerFid(generatedFid)
160
+ .then(async (registerFidResponse) => {
161
+ const checkinResponse = await this.executeCheckin();
162
+ return {
163
+ fidResponse: registerFidResponse,
164
+ checkinResponse: checkinResponse
165
+ };
166
+ })
167
+ .then(async (result) => {
168
+ const registerGcmResponse = await this.registerGcm(result.fidResponse, result.checkinResponse);
169
+ return {
170
+ ...result,
171
+ gcmResponse: registerGcmResponse,
172
+ };
173
+ }).catch((error) => {
174
+ throw error;
175
+ });
176
+ }
177
+ async renewPushCredentials(credentials) {
178
+ return await this.renewFidToken(credentials.fidResponse.fid, credentials.fidResponse.refreshToken)
179
+ .then(async (response) => {
180
+ credentials.fidResponse.authToken = response;
181
+ return await this.executeCheckin();
182
+ })
183
+ .then(async (response) => {
184
+ const registerGcmResponse = await this.registerGcm(credentials.fidResponse, response);
185
+ return {
186
+ fidResponse: credentials.fidResponse,
187
+ checkinResponse: response,
188
+ gcmResponse: registerGcmResponse,
189
+ };
190
+ })
191
+ .catch(() => {
192
+ return this.createPushCredentials();
193
+ });
194
+ }
195
+ async loginPushCredentials(credentials) {
196
+ return await this.executeCheckin()
197
+ .then(async (response) => {
198
+ const registerGcmResponse = await this.registerGcm(credentials.fidResponse, response);
199
+ return {
200
+ fidResponse: credentials.fidResponse,
201
+ checkinResponse: response,
202
+ gcmResponse: registerGcmResponse,
203
+ };
204
+ })
205
+ .catch(() => {
206
+ return this.createPushCredentials();
207
+ });
208
+ }
209
+ async executeCheckin() {
210
+ const url = "https://android.clients.google.com/checkin";
211
+ try {
212
+ const buffer = await (0, utils_1.buildCheckinRequest)();
213
+ const response = await (0, got_1.default)(url, {
214
+ method: "post",
215
+ body: Buffer.from(buffer),
216
+ headers: {
217
+ "Content-Type": "application/x-protobuf",
218
+ },
219
+ responseType: "buffer",
220
+ http2: false,
221
+ throwHttpErrors: false,
222
+ retry: {
223
+ limit: 3,
224
+ methods: ["POST"]
225
+ }
226
+ }).catch(error => {
227
+ this.log.error("executeCheckin - Error:", error);
228
+ return error;
229
+ });
230
+ if (response.statusCode == 200) {
231
+ return await (0, utils_1.parseCheckinResponse)(response.body);
232
+ }
233
+ else {
234
+ this.log.error("executeCheckin - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
235
+ throw new Error(`Google checkin failed with error: ${response.statusMessage}`);
236
+ }
237
+ }
238
+ catch (error) {
239
+ this.log.error("executeCheckin - Generic Error:", error);
240
+ throw new Error(`Google checkin failed with error: ${error}`);
241
+ }
242
+ }
243
+ async registerGcm(fidInstallationResponse, checkinResponse) {
244
+ const url = "https://android.clients.google.com/c2dm/register3";
245
+ const androidId = checkinResponse.androidId;
246
+ const fid = fidInstallationResponse.fid;
247
+ const securityToken = checkinResponse.securityToken;
248
+ const retry = 5;
249
+ try {
250
+ for (let retry_count = 1; retry_count <= retry; retry_count++) {
251
+ const response = await (0, got_1.default)(url, {
252
+ method: "post",
253
+ body: qs.stringify({
254
+ "X-subtype": `${this.APP_SENDER_ID}`,
255
+ sender: `${this.APP_SENDER_ID}`,
256
+ "X-app_ver": "741",
257
+ "X-osv": "25",
258
+ "X-cliv": "fiid-20.2.0",
259
+ "X-gmsv": "201216023",
260
+ "X-appid": `${fid}`,
261
+ "X-scope": "*",
262
+ "X-Goog-Firebase-Installations-Auth": `${fidInstallationResponse.authToken.token}`,
263
+ "X-gmp_app_id": `${this.APP_ID}`,
264
+ "X-Firebase-Client": "fire-abt/17.1.1+fire-installations/16.3.1+fire-android/+fire-analytics/17.4.2+fire-iid/20.2.0+fire-rc/17.0.0+fire-fcm/20.2.0+fire-cls/17.0.0+fire-cls-ndk/17.0.0+fire-core/19.3.0",
265
+ "X-firebase-app-name-hash": "R1dAH9Ui7M-ynoznwBdw01tLxhI",
266
+ "X-Firebase-Client-Log-Type": "1",
267
+ "X-app_ver_name": "v2.2.2_741",
268
+ app: `${this.APP_PACKAGE}`,
269
+ device: `${androidId}`,
270
+ app_ver: "741",
271
+ info: "g3EMJXXElLwaQEb1aBJ6XhxiHjPTUxc",
272
+ gcm_ver: "201216023",
273
+ plat: "0",
274
+ cert: `${this.APP_CERT_SHA1}`,
275
+ target_ver: "28",
276
+ }),
277
+ headers: {
278
+ Authorization: `AidLogin ${androidId}:${securityToken}`,
279
+ app: `${this.APP_PACKAGE}`,
280
+ gcm_ver: "201216023",
281
+ "User-Agent": "Android-GCM/1.5 (OnePlus5 NMF26X)",
282
+ "content-type": "application/x-www-form-urlencoded",
283
+ },
284
+ http2: false,
285
+ throwHttpErrors: false,
286
+ retry: {
287
+ limit: 3,
288
+ methods: ["POST"]
289
+ }
290
+ }).catch(error => {
291
+ this.log.error("registerGcm - Error:", error);
292
+ return error;
293
+ });
294
+ if (response.statusCode == 200) {
295
+ const result = response.body.split("=");
296
+ if (result[0] == "Error") {
297
+ this.log.debug("GCM register error, retry...", { retry: retry, retryCount: retry_count });
298
+ if (retry_count == retry)
299
+ throw new Error(`GCM-Register Error: ${result[1]}`);
300
+ }
301
+ else {
302
+ return {
303
+ token: result[1]
304
+ };
305
+ }
306
+ }
307
+ else {
308
+ this.log.error("registerGcm - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
309
+ throw new Error(`Google register to GCM failed with error: ${response.statusMessage}`);
310
+ }
311
+ await (0, utils_1.sleep)(10000 * retry_count);
312
+ }
313
+ throw new Error(`GCM-Register Error: Undefined!`);
314
+ }
315
+ catch (error) {
316
+ this.log.error("registerGcm - Generic Error:", error);
317
+ throw new Error(`Google register to GCM failed with error: ${error}`);
318
+ }
319
+ }
320
+ _normalizePushMessage(message) {
321
+ const normalized_message = {
322
+ name: "",
323
+ event_time: 0,
324
+ type: -1,
325
+ station_sn: "",
326
+ device_sn: ""
327
+ };
328
+ if (message.payload.payload) {
329
+ // CusPush
330
+ normalized_message.type = Number.parseInt(message.payload.type);
331
+ try {
332
+ normalized_message.event_time = message.payload.event_time !== undefined ? (0, utils_1.convertTimestampMs)(Number.parseInt(message.payload.event_time)) : Number.parseInt(message.payload.event_time);
333
+ }
334
+ catch (error) {
335
+ this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPush - event_time - Error:`, error);
336
+ }
337
+ normalized_message.station_sn = message.payload.station_sn;
338
+ if (normalized_message.type === types_1.DeviceType.FLOODLIGHT)
339
+ normalized_message.device_sn = message.payload.station_sn;
340
+ else
341
+ normalized_message.device_sn = message.payload.device_sn;
342
+ if ((0, utils_3.isEmpty)(normalized_message.device_sn) && !(0, utils_3.isEmpty)(normalized_message.station_sn)) {
343
+ normalized_message.device_sn = normalized_message.station_sn;
344
+ }
345
+ normalized_message.title = message.payload.title;
346
+ normalized_message.content = message.payload.content;
347
+ try {
348
+ normalized_message.push_time = message.payload.push_time !== undefined ? (0, utils_1.convertTimestampMs)(Number.parseInt(message.payload.push_time)) : Number.parseInt(message.payload.push_time);
349
+ }
350
+ catch (error) {
351
+ this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPush - push_time - Error:`, error);
352
+ }
353
+ if (normalized_message.type === types_1.DeviceType.HB3) {
354
+ const push_data = message.payload.payload;
355
+ normalized_message.name = push_data.name ? push_data.name : "";
356
+ normalized_message.channel = push_data.channel !== undefined ? push_data.channel : 0;
357
+ normalized_message.cipher = push_data.cipher !== undefined ? push_data.cipher : 0;
358
+ normalized_message.event_session = push_data.session_id !== undefined ? push_data.session_id : "";
359
+ normalized_message.event_type = push_data.a !== undefined ? push_data.a : push_data.event_type;
360
+ normalized_message.file_path = push_data.file_path !== undefined ? push_data.file_path : "";
361
+ normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
362
+ normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
363
+ normalized_message.notification_style = push_data.notification_style;
364
+ normalized_message.storage_type = push_data.storage_type !== undefined ? push_data.storage_type : 1;
365
+ normalized_message.msg_type = push_data.msg_type;
366
+ normalized_message.person_name = push_data.nick_name;
367
+ normalized_message.person_id = push_data.person_id;
368
+ normalized_message.tfcard_status = push_data.tfcard_status;
369
+ normalized_message.user_type = push_data.user;
370
+ normalized_message.user_name = push_data.user_name;
371
+ normalized_message.station_guard_mode = push_data.arming;
372
+ normalized_message.station_current_mode = push_data.mode;
373
+ normalized_message.alarm_delay = push_data.alarm_delay;
374
+ normalized_message.sound_alarm = push_data.alarm !== undefined ? push_data.alarm === 1 ? true : false : undefined;
375
+ }
376
+ else {
377
+ if (device_1.Device.isBatteryDoorbell(normalized_message.type) || device_1.Device.isWiredDoorbellDual(normalized_message.type)) {
378
+ const push_data = message.payload.payload;
379
+ normalized_message.name = push_data.name ? push_data.name : "";
380
+ //Get family face names from Doorbell Dual "Family Recognition" event
381
+ if (push_data.objects !== undefined) {
382
+ normalized_message.person_name = push_data.objects.names !== undefined ? push_data.objects.names.join(",") : "";
383
+ }
384
+ normalized_message.channel = push_data.channel !== undefined ? push_data.channel : 0;
385
+ normalized_message.cipher = push_data.cipher !== undefined ? push_data.cipher : 0;
386
+ normalized_message.event_session = push_data.session_id !== undefined ? push_data.session_id : "";
387
+ normalized_message.event_type = push_data.event_type;
388
+ normalized_message.file_path = push_data.file_path !== undefined && push_data.file_path !== "" && push_data.channel !== undefined ? (0, utils_2.getAbsoluteFilePath)(normalized_message.type, push_data.channel, push_data.file_path) : "";
389
+ normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
390
+ normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
391
+ normalized_message.notification_style = push_data.notification_style;
392
+ }
393
+ else if (device_1.Device.isIndoorCamera(normalized_message.type) ||
394
+ device_1.Device.isSoloCameras(normalized_message.type) ||
395
+ device_1.Device.isFloodLightT8420X(normalized_message.type, normalized_message.device_sn) ||
396
+ (device_1.Device.isFloodLight(normalized_message.type) && normalized_message.type !== types_1.DeviceType.FLOODLIGHT)) {
397
+ const push_data = message.payload.payload;
398
+ normalized_message.name = push_data.name ? push_data.name : "";
399
+ normalized_message.channel = push_data.channel;
400
+ normalized_message.cipher = push_data.cipher;
401
+ normalized_message.event_session = push_data.session_id;
402
+ normalized_message.event_type = push_data.event_type;
403
+ //normalized_message.file_path = push_data.file_path !== undefined && push_data.file_path !== "" && push_data.channel !== undefined ? getAbsoluteFilePath(normalized_message.type, push_data.channel, push_data.file_path) : "";
404
+ normalized_message.file_path = push_data.file_path;
405
+ normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
406
+ normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
407
+ normalized_message.notification_style = push_data.notification_style;
408
+ normalized_message.msg_type = push_data.msg_type;
409
+ normalized_message.timeout = push_data.timeout;
410
+ normalized_message.tfcard_status = push_data.tfcard_status;
411
+ normalized_message.storage_type = push_data.storage_type !== undefined ? push_data.storage_type : 1;
412
+ normalized_message.unique_id = push_data.unique_id;
413
+ }
414
+ else if (device_1.Device.isSmartSafe(normalized_message.type)) {
415
+ const push_data = message.payload.payload;
416
+ normalized_message.event_type = push_data.event_type;
417
+ normalized_message.event_value = push_data.event_value;
418
+ /*
419
+ event_value: {
420
+ type: 3, 3/4
421
+ action: 1,
422
+ figure_id: 0,
423
+ user_id: 0
424
+ }
425
+ */
426
+ normalized_message.name = push_data.dev_name !== undefined ? push_data.dev_name : "";
427
+ /*normalized_message.short_user_id = push_data.short_user_id !== undefined ? push_data.short_user_id : "";
428
+ normalized_message.user_id = push_data.user_id !== undefined ? push_data.user_id : "";*/
429
+ }
430
+ else if (device_1.Device.isLock(normalized_message.type)) {
431
+ const push_data = message.payload.payload;
432
+ normalized_message.event_type = push_data.event_type;
433
+ normalized_message.short_user_id = push_data.short_user_id !== undefined ? push_data.short_user_id : "";
434
+ normalized_message.user_id = push_data.user_id !== undefined ? push_data.user_id : "";
435
+ normalized_message.name = push_data.device_name !== undefined ? push_data.device_name : "";
436
+ }
437
+ else {
438
+ const push_data = message.payload.payload;
439
+ normalized_message.name = push_data.device_name && push_data.device_name !== null && push_data.device_name !== "" ? push_data.device_name : push_data.n ? push_data.n : "";
440
+ normalized_message.channel = push_data.c;
441
+ normalized_message.cipher = push_data.k;
442
+ normalized_message.event_session = push_data.session_id;
443
+ normalized_message.event_type = push_data.a;
444
+ normalized_message.file_path = push_data.c !== undefined && push_data.p !== undefined && push_data.p !== "" ? (0, utils_2.getAbsoluteFilePath)(normalized_message.type, push_data.c, push_data.p) : "";
445
+ normalized_message.pic_url = push_data.pic_url !== undefined ? push_data.pic_url : "";
446
+ normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
447
+ normalized_message.notification_style = push_data.notification_style;
448
+ normalized_message.tfcard_status = push_data.tfcard;
449
+ normalized_message.alarm_delay_type = push_data.alarm_type;
450
+ normalized_message.alarm_delay = push_data.alarm_delay;
451
+ normalized_message.alarm_type = push_data.type;
452
+ normalized_message.sound_alarm = push_data.alarm !== undefined ? push_data.alarm === 1 ? true : false : undefined;
453
+ normalized_message.user_name = push_data.user_name;
454
+ normalized_message.user_type = push_data.user;
455
+ normalized_message.user_id = push_data.user_id;
456
+ normalized_message.short_user_id = push_data.short_user_id;
457
+ normalized_message.station_guard_mode = push_data.arming;
458
+ normalized_message.station_current_mode = push_data.mode;
459
+ normalized_message.person_name = push_data.f;
460
+ normalized_message.sensor_open = push_data.e !== undefined ? push_data.e === "1" ? true : false : undefined;
461
+ normalized_message.device_online = push_data.m !== undefined ? push_data.m === 1 ? true : false : undefined;
462
+ try {
463
+ normalized_message.fetch_id = push_data.i !== undefined ? Number.parseInt(push_data.i) : undefined;
464
+ }
465
+ catch (error) {
466
+ this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPushData - fetch_id - Error:`, error);
467
+ }
468
+ normalized_message.sense_id = push_data.j;
469
+ normalized_message.battery_powered = push_data.batt_powered !== undefined ? push_data.batt_powered === 1 ? true : false : undefined;
470
+ try {
471
+ normalized_message.battery_low = push_data.bat_low !== undefined ? Number.parseInt(push_data.bat_low) : undefined;
472
+ }
473
+ catch (error) {
474
+ this.log.error(`Type ${types_1.DeviceType[normalized_message.type]} CusPushData - battery_low - Error:`, error);
475
+ }
476
+ normalized_message.storage_type = push_data.storage_type !== undefined ? push_data.storage_type : 1;
477
+ normalized_message.unique_id = push_data.unique_id;
478
+ normalized_message.automation_id = push_data.automation_id;
479
+ normalized_message.click_action = push_data.click_action;
480
+ normalized_message.news_id = push_data.news_id;
481
+ }
482
+ }
483
+ }
484
+ else if (message.payload.doorbell !== undefined) {
485
+ const push_data = (0, utils_3.parseJSON)(message.payload.doorbell, this.log);
486
+ if (push_data !== undefined) {
487
+ normalized_message.name = "Doorbell";
488
+ normalized_message.type = 5;
489
+ normalized_message.event_time = push_data.create_time !== undefined ? (0, utils_1.convertTimestampMs)(push_data.create_time) : push_data.create_time;
490
+ normalized_message.station_sn = push_data.device_sn;
491
+ normalized_message.device_sn = push_data.device_sn;
492
+ normalized_message.title = push_data.title;
493
+ normalized_message.content = push_data.content;
494
+ normalized_message.push_time = push_data.event_time !== undefined ? (0, utils_1.convertTimestampMs)(push_data.event_time) : push_data.event_time;
495
+ normalized_message.channel = push_data.channel;
496
+ normalized_message.cipher = push_data.cipher;
497
+ normalized_message.event_session = push_data.event_session;
498
+ normalized_message.event_type = push_data.event_type;
499
+ normalized_message.file_path = push_data.file_path;
500
+ normalized_message.pic_url = push_data.pic_url;
501
+ normalized_message.push_count = push_data.push_count !== undefined ? push_data.push_count : 1;
502
+ normalized_message.doorbell_url = push_data.url;
503
+ normalized_message.doorbell_url_ex = push_data.url_ex;
504
+ normalized_message.doorbell_video_url = push_data.video_url;
505
+ }
506
+ }
507
+ return normalized_message;
508
+ }
509
+ onMessage(message) {
510
+ this.log.debug("Raw push message received", message);
511
+ this.emit("raw message", message);
512
+ const normalized_message = this._normalizePushMessage(message);
513
+ this.log.debug("Normalized push message received", normalized_message);
514
+ this.emit("message", normalized_message);
515
+ }
516
+ getCurrentPushRetryDelay() {
517
+ const delay = this.retryDelay == 0 ? 5000 : this.retryDelay;
518
+ if (this.retryDelay < 60000)
519
+ this.retryDelay += 10000;
520
+ if (this.retryDelay >= 60000 && this.retryDelay < 600000)
521
+ this.retryDelay += 60000;
522
+ return delay;
523
+ }
524
+ setCredentials(credentials) {
525
+ this.credentials = credentials;
526
+ }
527
+ getCredentials() {
528
+ return this.credentials;
529
+ }
530
+ setPersistentIds(persistentIds) {
531
+ this.persistentIds = persistentIds;
532
+ }
533
+ getPersistentIds() {
534
+ return this.persistentIds;
535
+ }
536
+ async _open(renew = false) {
537
+ if (!this.credentials || Object.keys(this.credentials).length === 0 || (this.credentials && this.credentials.fidResponse && new Date().getTime() >= this.credentials.fidResponse.authToken.expiresAt)) {
538
+ this.log.debug(`Create new push credentials...`);
539
+ this.credentials = await this.createPushCredentials().catch(error => {
540
+ this.log.error("Create push credentials Error:", error);
541
+ return undefined;
542
+ });
543
+ }
544
+ else if (this.credentials && renew) {
545
+ this.log.debug(`Renew push credentials...`);
546
+ this.credentials = await this.renewPushCredentials(this.credentials).catch(error => {
547
+ this.log.error("Push credentials renew Error:", error);
548
+ return undefined;
549
+ });
550
+ }
551
+ else {
552
+ this.log.debug(`Login with previous push credentials...`, this.credentials);
553
+ this.credentials = await this.loginPushCredentials(this.credentials).catch(error => {
554
+ this.log.error("Push credentials login Error:", error);
555
+ return undefined;
556
+ });
557
+ }
558
+ if (this.credentials) {
559
+ this.emit("credential", this.credentials);
560
+ this.clearCredentialsTimeout();
561
+ this.credentialsTimeout = setTimeout(async () => {
562
+ this.log.info("Push notification token is expiring, renew it.");
563
+ await this._open(true);
564
+ }, this.credentials.fidResponse.authToken.expiresAt - new Date().getTime() - 60000);
565
+ if (this.pushClient) {
566
+ this.pushClient.removeAllListeners();
567
+ }
568
+ this.pushClient = await client_1.PushClient.init({
569
+ androidId: this.credentials.checkinResponse.androidId,
570
+ securityToken: this.credentials.checkinResponse.securityToken,
571
+ }, this.log);
572
+ if (this.persistentIds)
573
+ this.pushClient.setPersistentIds(this.persistentIds);
574
+ const token = this.credentials.gcmResponse.token;
575
+ this.pushClient.on("connect", () => {
576
+ this.emit("connect", token);
577
+ this.connected = true;
578
+ this.connecting = false;
579
+ });
580
+ this.pushClient.on("close", () => {
581
+ this.emit("close");
582
+ this.connected = false;
583
+ this.connecting = false;
584
+ });
585
+ this.pushClient.on("message", (msg) => this.onMessage(msg));
586
+ this.pushClient.connect();
587
+ }
588
+ else {
589
+ this.emit("close");
590
+ this.connected = false;
591
+ this.connecting = false;
592
+ this.log.error("Push notifications are disabled, because the registration failed!");
593
+ }
594
+ }
595
+ async open() {
596
+ if (!this.connecting && !this.connected) {
597
+ this.connecting = true;
598
+ await this._open().catch((error) => {
599
+ this.log.error(`Got exception trying to initialize push notifications`, error);
600
+ });
601
+ if (!this.credentials) {
602
+ this.clearRetryTimeout();
603
+ const delay = this.getCurrentPushRetryDelay();
604
+ this.log.info(`Retry to register/login for push notification in ${delay / 1000} seconds...`);
605
+ this.retryTimeout = setTimeout(async () => {
606
+ this.log.info(`Retry to register/login for push notification`);
607
+ await this.open();
608
+ }, delay);
609
+ }
610
+ else {
611
+ this.resetRetryTimeout();
612
+ this.emit("credential", this.credentials);
613
+ }
614
+ }
615
+ return this.credentials;
616
+ }
617
+ close() {
618
+ var _a;
619
+ this.resetRetryTimeout();
620
+ this.clearCredentialsTimeout();
621
+ (_a = this.pushClient) === null || _a === void 0 ? void 0 : _a.close();
622
+ }
623
+ clearCredentialsTimeout() {
624
+ if (this.credentialsTimeout) {
625
+ clearTimeout(this.credentialsTimeout);
626
+ this.credentialsTimeout = undefined;
627
+ }
628
+ }
629
+ clearRetryTimeout() {
630
+ if (this.retryTimeout) {
631
+ clearTimeout(this.retryTimeout);
632
+ this.retryTimeout = undefined;
633
+ }
634
+ }
635
+ resetRetryTimeout() {
636
+ this.clearRetryTimeout();
637
+ this.retryDelay = 0;
638
+ }
639
+ isConnected() {
640
+ return this.connected;
641
+ }
642
+ }
643
+ exports.PushNotificationService = PushNotificationService;
644
644
  //# sourceMappingURL=service.js.map