eufy-security-client 2.4.2 → 2.4.3

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 (85) hide show
  1. package/README.md +6 -0
  2. package/build/error.d.ts +57 -57
  3. package/build/error.js +155 -155
  4. package/build/eufysecurity.d.ts +161 -161
  5. package/build/eufysecurity.js +2091 -2091
  6. package/build/http/api.d.ts +90 -90
  7. package/build/http/api.js +1407 -1407
  8. package/build/http/api.js.map +1 -1
  9. package/build/http/cache.d.ts +8 -8
  10. package/build/http/cache.js +33 -33
  11. package/build/http/const.d.ts +3 -3
  12. package/build/http/const.js +8545 -8545
  13. package/build/http/device.d.ts +360 -360
  14. package/build/http/device.js +2793 -2793
  15. package/build/http/device.js.map +1 -1
  16. package/build/http/error.d.ts +28 -28
  17. package/build/http/error.js +76 -76
  18. package/build/http/index.d.ts +10 -10
  19. package/build/http/index.js +29 -29
  20. package/build/http/interfaces.d.ts +202 -202
  21. package/build/http/interfaces.js +2 -2
  22. package/build/http/models.d.ts +561 -561
  23. package/build/http/models.js +2 -2
  24. package/build/http/parameter.d.ts +5 -5
  25. package/build/http/parameter.js +75 -75
  26. package/build/http/station.d.ts +292 -292
  27. package/build/http/station.js +6780 -6780
  28. package/build/http/station.js.map +1 -1
  29. package/build/http/types.d.ts +945 -945
  30. package/build/http/types.js +6070 -6070
  31. package/build/http/utils.d.ts +37 -37
  32. package/build/http/utils.js +370 -370
  33. package/build/index.d.ts +7 -7
  34. package/build/index.js +25 -25
  35. package/build/interfaces.d.ts +113 -113
  36. package/build/interfaces.js +2 -2
  37. package/build/mqtt/interface.d.ts +6 -6
  38. package/build/mqtt/interface.js +2 -2
  39. package/build/mqtt/model.d.ts +24 -24
  40. package/build/mqtt/model.js +2 -2
  41. package/build/mqtt/service.d.ts +30 -30
  42. package/build/mqtt/service.js +168 -168
  43. package/build/mqtt/service.js.map +1 -1
  44. package/build/p2p/ble.d.ts +47 -47
  45. package/build/p2p/ble.js +188 -188
  46. package/build/p2p/ble.js.map +1 -1
  47. package/build/p2p/error.d.ts +24 -24
  48. package/build/p2p/error.js +67 -67
  49. package/build/p2p/index.d.ts +8 -8
  50. package/build/p2p/index.js +27 -27
  51. package/build/p2p/interfaces.d.ts +162 -162
  52. package/build/p2p/interfaces.js +2 -2
  53. package/build/p2p/models.d.ts +146 -146
  54. package/build/p2p/models.js +2 -2
  55. package/build/p2p/session.d.ts +168 -168
  56. package/build/p2p/session.js +2087 -2087
  57. package/build/p2p/session.js.map +1 -1
  58. package/build/p2p/talkback.d.ts +10 -10
  59. package/build/p2p/talkback.js +22 -22
  60. package/build/p2p/types.d.ts +923 -923
  61. package/build/p2p/types.js +957 -957
  62. package/build/p2p/utils.d.ts +56 -56
  63. package/build/p2p/utils.js +653 -653
  64. package/build/push/client.d.ts +51 -51
  65. package/build/push/client.js +311 -311
  66. package/build/push/client.js.map +1 -1
  67. package/build/push/index.d.ts +5 -5
  68. package/build/push/index.js +24 -24
  69. package/build/push/interfaces.d.ts +19 -19
  70. package/build/push/interfaces.js +2 -2
  71. package/build/push/models.d.ts +292 -292
  72. package/build/push/models.js +30 -30
  73. package/build/push/parser.d.ts +28 -28
  74. package/build/push/parser.js +215 -215
  75. package/build/push/parser.js.map +1 -1
  76. package/build/push/service.d.ts +45 -45
  77. package/build/push/service.js +643 -643
  78. package/build/push/service.js.map +1 -1
  79. package/build/push/types.d.ts +176 -176
  80. package/build/push/types.js +192 -192
  81. package/build/push/utils.d.ts +7 -7
  82. package/build/push/utils.js +102 -102
  83. package/build/utils.d.ts +13 -13
  84. package/build/utils.js +191 -191
  85. package/package.json +9 -9
@@ -1,312 +1,312 @@
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
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.PushClient = void 0;
27
- const Long = __importStar(require("long"));
28
- const path = __importStar(require("path"));
29
- const protobuf_typescript_1 = require("protobuf-typescript");
30
- const tls = __importStar(require("tls"));
31
- const tiny_typed_emitter_1 = require("tiny-typed-emitter");
32
- const ts_log_1 = require("ts-log");
33
- const models_1 = require("./models");
34
- const parser_1 = require("./parser");
35
- const utils_1 = require("../utils");
36
- class PushClient extends tiny_typed_emitter_1.TypedEmitter {
37
- constructor(pushClientParser, auth, log = ts_log_1.dummyLogger) {
38
- super();
39
- this.HOST = "mtalk.google.com";
40
- this.PORT = 5228;
41
- this.MCS_VERSION = 41;
42
- this.HEARTBEAT_INTERVAL = 5 * 60 * 1000;
43
- this.loggedIn = false;
44
- this.streamId = 0;
45
- this.lastStreamIdReported = -1;
46
- this.currentDelay = 0;
47
- this.persistentIds = [];
48
- this.log = log;
49
- this.pushClientParser = pushClientParser;
50
- this.auth = auth;
51
- }
52
- static async init(auth, log = ts_log_1.dummyLogger) {
53
- this.proto = await (0, protobuf_typescript_1.load)(path.join(__dirname, "./proto/mcs.proto"));
54
- const pushClientParser = await parser_1.PushClientParser.init(log);
55
- return new PushClient(pushClientParser, auth, log);
56
- }
57
- initialize() {
58
- this.loggedIn = false;
59
- this.streamId = 0;
60
- this.lastStreamIdReported = -1;
61
- if (this.client) {
62
- this.client.removeAllListeners();
63
- this.client.destroy();
64
- this.client = undefined;
65
- }
66
- this.pushClientParser.resetState();
67
- if (this.reconnectTimeout) {
68
- clearTimeout(this.reconnectTimeout);
69
- this.reconnectTimeout = undefined;
70
- }
71
- }
72
- getPersistentIds() {
73
- return this.persistentIds;
74
- }
75
- setPersistentIds(ids) {
76
- this.persistentIds = ids;
77
- }
78
- connect() {
79
- this.initialize();
80
- this.pushClientParser.on("message", (message) => this.handleParsedMessage(message));
81
- this.client = tls.connect(this.PORT, this.HOST, {
82
- rejectUnauthorized: false,
83
- });
84
- this.client.setKeepAlive(true);
85
- // For debugging purposes
86
- //this.client.enableTrace();
87
- this.client.on("connect", () => this.onSocketConnect());
88
- this.client.on("close", () => this.onSocketClose());
89
- this.client.on("error", (error) => this.onSocketError(error));
90
- this.client.on("data", (newData) => this.onSocketData(newData));
91
- this.client.write(this.buildLoginRequest());
92
- }
93
- buildLoginRequest() {
94
- const androidId = this.auth.androidId;
95
- const securityToken = this.auth.securityToken;
96
- const LoginRequestType = PushClient.proto.lookupType("mcs_proto.LoginRequest");
97
- const hexAndroidId = Long.fromString(androidId).toString(16);
98
- const loginRequest = {
99
- adaptiveHeartbeat: false,
100
- authService: 2,
101
- authToken: securityToken,
102
- id: "chrome-63.0.3234.0",
103
- domain: "mcs.android.com",
104
- deviceId: `android-${hexAndroidId}`,
105
- networkType: 1,
106
- resource: androidId,
107
- user: androidId,
108
- useRmq2: true,
109
- setting: [{ name: "new_vc", value: "1" }],
110
- clientEvent: [],
111
- receivedPersistentId: this.persistentIds,
112
- };
113
- const errorMessage = LoginRequestType.verify(loginRequest);
114
- if (errorMessage) {
115
- throw new Error(errorMessage);
116
- }
117
- const buffer = LoginRequestType.encodeDelimited(loginRequest).finish();
118
- return Buffer.concat([Buffer.from([this.MCS_VERSION, models_1.MessageTag.LoginRequest]), buffer]);
119
- }
120
- buildHeartbeatPingRequest(stream_id) {
121
- const heartbeatPingRequest = {};
122
- if (stream_id) {
123
- heartbeatPingRequest.last_stream_id_received = stream_id;
124
- }
125
- this.log.debug(`heartbeatPingRequest`, heartbeatPingRequest);
126
- const HeartbeatPingRequestType = PushClient.proto.lookupType("mcs_proto.HeartbeatPing");
127
- const errorMessage = HeartbeatPingRequestType.verify(heartbeatPingRequest);
128
- if (errorMessage) {
129
- throw new Error(errorMessage);
130
- }
131
- const buffer = HeartbeatPingRequestType.encodeDelimited(heartbeatPingRequest).finish();
132
- return Buffer.concat([Buffer.from([models_1.MessageTag.HeartbeatPing]), buffer]);
133
- }
134
- buildHeartbeatAckRequest(stream_id, status) {
135
- const heartbeatAckRequest = {};
136
- if (stream_id && !status) {
137
- heartbeatAckRequest.last_stream_id_received = stream_id;
138
- }
139
- else if (!stream_id && status) {
140
- heartbeatAckRequest.status = status;
141
- }
142
- else {
143
- heartbeatAckRequest.last_stream_id_received = stream_id;
144
- heartbeatAckRequest.status = status;
145
- }
146
- this.log.debug(`heartbeatAckRequest`, heartbeatAckRequest);
147
- const HeartbeatAckRequestType = PushClient.proto.lookupType("mcs_proto.HeartbeatAck");
148
- const errorMessage = HeartbeatAckRequestType.verify(heartbeatAckRequest);
149
- if (errorMessage) {
150
- throw new Error(errorMessage);
151
- }
152
- const buffer = HeartbeatAckRequestType.encodeDelimited(heartbeatAckRequest).finish();
153
- return Buffer.concat([Buffer.from([models_1.MessageTag.HeartbeatAck]), buffer]);
154
- }
155
- onSocketData(newData) {
156
- this.pushClientParser.handleData(newData);
157
- }
158
- onSocketConnect() {
159
- //
160
- }
161
- onSocketClose() {
162
- this.loggedIn = false;
163
- if (this.heartbeatTimeout) {
164
- clearTimeout(this.heartbeatTimeout);
165
- this.heartbeatTimeout = undefined;
166
- }
167
- this.emit("close");
168
- this.scheduleReconnect();
169
- }
170
- onSocketError(error) {
171
- this.log.error(`onSocketError:`, error);
172
- }
173
- handleParsedMessage(message) {
174
- this.resetCurrentDelay();
175
- switch (message.tag) {
176
- case models_1.MessageTag.DataMessageStanza:
177
- this.log.debug(`DataMessageStanza`, message);
178
- if (message.object && message.object.persistentId)
179
- this.persistentIds.push(message.object.persistentId);
180
- this.emit("message", this.convertPayloadMessage(message));
181
- break;
182
- case models_1.MessageTag.HeartbeatPing:
183
- this.handleHeartbeatPing(message);
184
- break;
185
- case models_1.MessageTag.HeartbeatAck:
186
- this.handleHeartbeatAck(message);
187
- break;
188
- case models_1.MessageTag.Close:
189
- this.log.debug(`Close: Server requested close`, message);
190
- break;
191
- case models_1.MessageTag.LoginResponse:
192
- this.log.debug("Login response: GCM -> logged in -> waiting for push messages...");
193
- this.loggedIn = true;
194
- this.persistentIds = [];
195
- this.emit("connect");
196
- this.heartbeatTimeout = setTimeout(() => {
197
- this.scheduleHeartbeat(this);
198
- }, this.getHeartbeatInterval());
199
- break;
200
- case models_1.MessageTag.LoginRequest:
201
- this.log.debug(`Login request`, message);
202
- break;
203
- case models_1.MessageTag.IqStanza:
204
- this.log.debug(`IqStanza: Not implemented`, message);
205
- break;
206
- default:
207
- this.log.debug(`Unknown message`, message);
208
- return;
209
- }
210
- this.streamId++;
211
- }
212
- handleHeartbeatPing(message) {
213
- this.log.debug(`Heartbeat ping`, message);
214
- let streamId = undefined;
215
- let status = undefined;
216
- if (this.newStreamIdAvailable()) {
217
- streamId = this.getStreamId();
218
- }
219
- if (message.object && message.object.status) {
220
- status = message.object.status;
221
- }
222
- if (this.client)
223
- this.client.write(this.buildHeartbeatAckRequest(streamId, status));
224
- }
225
- handleHeartbeatAck(message) {
226
- this.log.debug(`Heartbeat acknowledge`, message);
227
- }
228
- convertPayloadMessage(message) {
229
- const { appData, ...otherData } = message.object;
230
- const messageData = {};
231
- appData.forEach((kv) => {
232
- if (kv.key === "payload") {
233
- const payload = (0, utils_1.parseJSON)(Buffer.from(kv.value, "base64").toString("utf8"), this.log);
234
- messageData[kv.key] = payload;
235
- }
236
- else {
237
- messageData[kv.key] = kv.value;
238
- }
239
- });
240
- return {
241
- ...otherData,
242
- payload: messageData,
243
- };
244
- }
245
- getStreamId() {
246
- this.lastStreamIdReported = this.streamId;
247
- return this.streamId;
248
- }
249
- newStreamIdAvailable() {
250
- return this.lastStreamIdReported != this.streamId;
251
- }
252
- scheduleHeartbeat(client) {
253
- if (client.sendHeartbeat()) {
254
- this.heartbeatTimeout = setTimeout(() => {
255
- this.scheduleHeartbeat(client);
256
- }, client.getHeartbeatInterval());
257
- }
258
- else {
259
- this.log.debug("Heartbeat disabled!");
260
- }
261
- }
262
- sendHeartbeat() {
263
- let streamId = undefined;
264
- if (this.newStreamIdAvailable()) {
265
- streamId = this.getStreamId();
266
- }
267
- if (this.client && this.isConnected()) {
268
- this.log.debug(`Sending heartbeat...`, streamId);
269
- this.client.write(this.buildHeartbeatPingRequest(streamId));
270
- return true;
271
- }
272
- else {
273
- this.log.debug("No more connected, reconnect...");
274
- this.scheduleReconnect();
275
- }
276
- return false;
277
- }
278
- isConnected() {
279
- return this.loggedIn;
280
- }
281
- getHeartbeatInterval() {
282
- return this.HEARTBEAT_INTERVAL;
283
- }
284
- getCurrentDelay() {
285
- const delay = this.currentDelay == 0 ? 5000 : this.currentDelay;
286
- if (this.currentDelay < 60000)
287
- this.currentDelay += 10000;
288
- if (this.currentDelay >= 60000 && this.currentDelay < 600000)
289
- this.currentDelay += 60000;
290
- return delay;
291
- }
292
- resetCurrentDelay() {
293
- this.currentDelay = 0;
294
- }
295
- scheduleReconnect() {
296
- const delay = this.getCurrentDelay();
297
- this.log.debug("Schedule reconnect...", { delay: delay });
298
- if (!this.reconnectTimeout)
299
- this.reconnectTimeout = setTimeout(() => {
300
- this.connect();
301
- }, delay);
302
- }
303
- close() {
304
- const wasConnected = this.isConnected();
305
- this.initialize();
306
- if (wasConnected)
307
- this.emit("close");
308
- }
309
- }
310
- exports.PushClient = PushClient;
311
- PushClient.proto = null;
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
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.PushClient = void 0;
27
+ const Long = __importStar(require("long"));
28
+ const path = __importStar(require("path"));
29
+ const protobuf_typescript_1 = require("protobuf-typescript");
30
+ const tls = __importStar(require("tls"));
31
+ const tiny_typed_emitter_1 = require("tiny-typed-emitter");
32
+ const ts_log_1 = require("ts-log");
33
+ const models_1 = require("./models");
34
+ const parser_1 = require("./parser");
35
+ const utils_1 = require("../utils");
36
+ class PushClient extends tiny_typed_emitter_1.TypedEmitter {
37
+ constructor(pushClientParser, auth, log = ts_log_1.dummyLogger) {
38
+ super();
39
+ this.HOST = "mtalk.google.com";
40
+ this.PORT = 5228;
41
+ this.MCS_VERSION = 41;
42
+ this.HEARTBEAT_INTERVAL = 5 * 60 * 1000;
43
+ this.loggedIn = false;
44
+ this.streamId = 0;
45
+ this.lastStreamIdReported = -1;
46
+ this.currentDelay = 0;
47
+ this.persistentIds = [];
48
+ this.log = log;
49
+ this.pushClientParser = pushClientParser;
50
+ this.auth = auth;
51
+ }
52
+ static async init(auth, log = ts_log_1.dummyLogger) {
53
+ this.proto = await (0, protobuf_typescript_1.load)(path.join(__dirname, "./proto/mcs.proto"));
54
+ const pushClientParser = await parser_1.PushClientParser.init(log);
55
+ return new PushClient(pushClientParser, auth, log);
56
+ }
57
+ initialize() {
58
+ this.loggedIn = false;
59
+ this.streamId = 0;
60
+ this.lastStreamIdReported = -1;
61
+ if (this.client) {
62
+ this.client.removeAllListeners();
63
+ this.client.destroy();
64
+ this.client = undefined;
65
+ }
66
+ this.pushClientParser.resetState();
67
+ if (this.reconnectTimeout) {
68
+ clearTimeout(this.reconnectTimeout);
69
+ this.reconnectTimeout = undefined;
70
+ }
71
+ }
72
+ getPersistentIds() {
73
+ return this.persistentIds;
74
+ }
75
+ setPersistentIds(ids) {
76
+ this.persistentIds = ids;
77
+ }
78
+ connect() {
79
+ this.initialize();
80
+ this.pushClientParser.on("message", (message) => this.handleParsedMessage(message));
81
+ this.client = tls.connect(this.PORT, this.HOST, {
82
+ rejectUnauthorized: false,
83
+ });
84
+ this.client.setKeepAlive(true);
85
+ // For debugging purposes
86
+ //this.client.enableTrace();
87
+ this.client.on("connect", () => this.onSocketConnect());
88
+ this.client.on("close", () => this.onSocketClose());
89
+ this.client.on("error", (error) => this.onSocketError(error));
90
+ this.client.on("data", (newData) => this.onSocketData(newData));
91
+ this.client.write(this.buildLoginRequest());
92
+ }
93
+ buildLoginRequest() {
94
+ const androidId = this.auth.androidId;
95
+ const securityToken = this.auth.securityToken;
96
+ const LoginRequestType = PushClient.proto.lookupType("mcs_proto.LoginRequest");
97
+ const hexAndroidId = Long.fromString(androidId).toString(16);
98
+ const loginRequest = {
99
+ adaptiveHeartbeat: false,
100
+ authService: 2,
101
+ authToken: securityToken,
102
+ id: "chrome-63.0.3234.0",
103
+ domain: "mcs.android.com",
104
+ deviceId: `android-${hexAndroidId}`,
105
+ networkType: 1,
106
+ resource: androidId,
107
+ user: androidId,
108
+ useRmq2: true,
109
+ setting: [{ name: "new_vc", value: "1" }],
110
+ clientEvent: [],
111
+ receivedPersistentId: this.persistentIds,
112
+ };
113
+ const errorMessage = LoginRequestType.verify(loginRequest);
114
+ if (errorMessage) {
115
+ throw new Error(errorMessage);
116
+ }
117
+ const buffer = LoginRequestType.encodeDelimited(loginRequest).finish();
118
+ return Buffer.concat([Buffer.from([this.MCS_VERSION, models_1.MessageTag.LoginRequest]), buffer]);
119
+ }
120
+ buildHeartbeatPingRequest(stream_id) {
121
+ const heartbeatPingRequest = {};
122
+ if (stream_id) {
123
+ heartbeatPingRequest.last_stream_id_received = stream_id;
124
+ }
125
+ this.log.debug(`heartbeatPingRequest`, heartbeatPingRequest);
126
+ const HeartbeatPingRequestType = PushClient.proto.lookupType("mcs_proto.HeartbeatPing");
127
+ const errorMessage = HeartbeatPingRequestType.verify(heartbeatPingRequest);
128
+ if (errorMessage) {
129
+ throw new Error(errorMessage);
130
+ }
131
+ const buffer = HeartbeatPingRequestType.encodeDelimited(heartbeatPingRequest).finish();
132
+ return Buffer.concat([Buffer.from([models_1.MessageTag.HeartbeatPing]), buffer]);
133
+ }
134
+ buildHeartbeatAckRequest(stream_id, status) {
135
+ const heartbeatAckRequest = {};
136
+ if (stream_id && !status) {
137
+ heartbeatAckRequest.last_stream_id_received = stream_id;
138
+ }
139
+ else if (!stream_id && status) {
140
+ heartbeatAckRequest.status = status;
141
+ }
142
+ else {
143
+ heartbeatAckRequest.last_stream_id_received = stream_id;
144
+ heartbeatAckRequest.status = status;
145
+ }
146
+ this.log.debug(`heartbeatAckRequest`, heartbeatAckRequest);
147
+ const HeartbeatAckRequestType = PushClient.proto.lookupType("mcs_proto.HeartbeatAck");
148
+ const errorMessage = HeartbeatAckRequestType.verify(heartbeatAckRequest);
149
+ if (errorMessage) {
150
+ throw new Error(errorMessage);
151
+ }
152
+ const buffer = HeartbeatAckRequestType.encodeDelimited(heartbeatAckRequest).finish();
153
+ return Buffer.concat([Buffer.from([models_1.MessageTag.HeartbeatAck]), buffer]);
154
+ }
155
+ onSocketData(newData) {
156
+ this.pushClientParser.handleData(newData);
157
+ }
158
+ onSocketConnect() {
159
+ //
160
+ }
161
+ onSocketClose() {
162
+ this.loggedIn = false;
163
+ if (this.heartbeatTimeout) {
164
+ clearTimeout(this.heartbeatTimeout);
165
+ this.heartbeatTimeout = undefined;
166
+ }
167
+ this.emit("close");
168
+ this.scheduleReconnect();
169
+ }
170
+ onSocketError(error) {
171
+ this.log.error(`onSocketError:`, error);
172
+ }
173
+ handleParsedMessage(message) {
174
+ this.resetCurrentDelay();
175
+ switch (message.tag) {
176
+ case models_1.MessageTag.DataMessageStanza:
177
+ this.log.debug(`DataMessageStanza`, message);
178
+ if (message.object && message.object.persistentId)
179
+ this.persistentIds.push(message.object.persistentId);
180
+ this.emit("message", this.convertPayloadMessage(message));
181
+ break;
182
+ case models_1.MessageTag.HeartbeatPing:
183
+ this.handleHeartbeatPing(message);
184
+ break;
185
+ case models_1.MessageTag.HeartbeatAck:
186
+ this.handleHeartbeatAck(message);
187
+ break;
188
+ case models_1.MessageTag.Close:
189
+ this.log.debug(`Close: Server requested close`, message);
190
+ break;
191
+ case models_1.MessageTag.LoginResponse:
192
+ this.log.debug("Login response: GCM -> logged in -> waiting for push messages...");
193
+ this.loggedIn = true;
194
+ this.persistentIds = [];
195
+ this.emit("connect");
196
+ this.heartbeatTimeout = setTimeout(() => {
197
+ this.scheduleHeartbeat(this);
198
+ }, this.getHeartbeatInterval());
199
+ break;
200
+ case models_1.MessageTag.LoginRequest:
201
+ this.log.debug(`Login request`, message);
202
+ break;
203
+ case models_1.MessageTag.IqStanza:
204
+ this.log.debug(`IqStanza: Not implemented`, message);
205
+ break;
206
+ default:
207
+ this.log.debug(`Unknown message`, message);
208
+ return;
209
+ }
210
+ this.streamId++;
211
+ }
212
+ handleHeartbeatPing(message) {
213
+ this.log.debug(`Heartbeat ping`, message);
214
+ let streamId = undefined;
215
+ let status = undefined;
216
+ if (this.newStreamIdAvailable()) {
217
+ streamId = this.getStreamId();
218
+ }
219
+ if (message.object && message.object.status) {
220
+ status = message.object.status;
221
+ }
222
+ if (this.client)
223
+ this.client.write(this.buildHeartbeatAckRequest(streamId, status));
224
+ }
225
+ handleHeartbeatAck(message) {
226
+ this.log.debug(`Heartbeat acknowledge`, message);
227
+ }
228
+ convertPayloadMessage(message) {
229
+ const { appData, ...otherData } = message.object;
230
+ const messageData = {};
231
+ appData.forEach((kv) => {
232
+ if (kv.key === "payload") {
233
+ const payload = (0, utils_1.parseJSON)(Buffer.from(kv.value, "base64").toString("utf8"), this.log);
234
+ messageData[kv.key] = payload;
235
+ }
236
+ else {
237
+ messageData[kv.key] = kv.value;
238
+ }
239
+ });
240
+ return {
241
+ ...otherData,
242
+ payload: messageData,
243
+ };
244
+ }
245
+ getStreamId() {
246
+ this.lastStreamIdReported = this.streamId;
247
+ return this.streamId;
248
+ }
249
+ newStreamIdAvailable() {
250
+ return this.lastStreamIdReported != this.streamId;
251
+ }
252
+ scheduleHeartbeat(client) {
253
+ if (client.sendHeartbeat()) {
254
+ this.heartbeatTimeout = setTimeout(() => {
255
+ this.scheduleHeartbeat(client);
256
+ }, client.getHeartbeatInterval());
257
+ }
258
+ else {
259
+ this.log.debug("Heartbeat disabled!");
260
+ }
261
+ }
262
+ sendHeartbeat() {
263
+ let streamId = undefined;
264
+ if (this.newStreamIdAvailable()) {
265
+ streamId = this.getStreamId();
266
+ }
267
+ if (this.client && this.isConnected()) {
268
+ this.log.debug(`Sending heartbeat...`, streamId);
269
+ this.client.write(this.buildHeartbeatPingRequest(streamId));
270
+ return true;
271
+ }
272
+ else {
273
+ this.log.debug("No more connected, reconnect...");
274
+ this.scheduleReconnect();
275
+ }
276
+ return false;
277
+ }
278
+ isConnected() {
279
+ return this.loggedIn;
280
+ }
281
+ getHeartbeatInterval() {
282
+ return this.HEARTBEAT_INTERVAL;
283
+ }
284
+ getCurrentDelay() {
285
+ const delay = this.currentDelay == 0 ? 5000 : this.currentDelay;
286
+ if (this.currentDelay < 60000)
287
+ this.currentDelay += 10000;
288
+ if (this.currentDelay >= 60000 && this.currentDelay < 600000)
289
+ this.currentDelay += 60000;
290
+ return delay;
291
+ }
292
+ resetCurrentDelay() {
293
+ this.currentDelay = 0;
294
+ }
295
+ scheduleReconnect() {
296
+ const delay = this.getCurrentDelay();
297
+ this.log.debug("Schedule reconnect...", { delay: delay });
298
+ if (!this.reconnectTimeout)
299
+ this.reconnectTimeout = setTimeout(() => {
300
+ this.connect();
301
+ }, delay);
302
+ }
303
+ close() {
304
+ const wasConnected = this.isConnected();
305
+ this.initialize();
306
+ if (wasConnected)
307
+ this.emit("close");
308
+ }
309
+ }
310
+ PushClient.proto = null;
311
+ exports.PushClient = PushClient;
312
312
  //# sourceMappingURL=client.js.map