@mtcute/core 0.1.1 → 0.1.2
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/cjs/network/auth-key.test.d.ts +1 -0
- package/cjs/network/auth-key.test.js +111 -0
- package/cjs/network/auth-key.test.js.map +1 -0
- package/cjs/network/config-manager.js +2 -1
- package/cjs/network/config-manager.js.map +1 -1
- package/cjs/network/config-manager.test.d.ts +1 -0
- package/cjs/network/config-manager.test.js +170 -0
- package/cjs/network/config-manager.test.js.map +1 -0
- package/cjs/network/network-manager.js +1 -1
- package/cjs/network/persistent-connection.test.d.ts +1 -0
- package/cjs/network/persistent-connection.test.js +157 -0
- package/cjs/network/persistent-connection.test.js.map +1 -0
- package/cjs/network/session-connection.js +3 -2
- package/cjs/network/session-connection.js.map +1 -1
- package/cjs/network/transports/intermediate.test.d.ts +1 -0
- package/cjs/network/transports/intermediate.test.js +86 -0
- package/cjs/network/transports/intermediate.test.js.map +1 -0
- package/cjs/network/transports/obfuscated.js +1 -1
- package/cjs/network/transports/obfuscated.js.map +1 -1
- package/cjs/network/transports/obfuscated.test.d.ts +1 -0
- package/cjs/network/transports/obfuscated.test.js +131 -0
- package/cjs/network/transports/obfuscated.test.js.map +1 -0
- package/cjs/network/transports/tcp.js +1 -1
- package/cjs/network/transports/tcp.js.map +1 -1
- package/cjs/network/transports/tcp.test.d.ts +1 -0
- package/cjs/network/transports/tcp.test.js +97 -0
- package/cjs/network/transports/tcp.test.js.map +1 -0
- package/cjs/network/transports/websocket.test.d.ts +1 -0
- package/cjs/network/transports/websocket.test.js +91 -0
- package/cjs/network/transports/websocket.test.js.map +1 -0
- package/cjs/storage/json.test.d.ts +1 -0
- package/cjs/storage/json.test.js +37 -0
- package/cjs/storage/json.test.js.map +1 -0
- package/cjs/storage/localstorage.test.d.ts +1 -0
- package/cjs/storage/localstorage.test.js +23 -0
- package/cjs/storage/localstorage.test.js.map +1 -0
- package/cjs/storage/memory.test.d.ts +1 -0
- package/cjs/storage/memory.test.js +47 -0
- package/cjs/storage/memory.test.js.map +1 -0
- package/cjs/utils/async-lock.test.d.ts +1 -0
- package/cjs/utils/async-lock.test.js +25 -0
- package/cjs/utils/async-lock.test.js.map +1 -0
- package/cjs/utils/bigint-utils.test.d.ts +1 -0
- package/cjs/utils/bigint-utils.test.js +150 -0
- package/cjs/utils/bigint-utils.test.js.map +1 -0
- package/cjs/utils/buffer-utils.test.d.ts +1 -0
- package/cjs/utils/buffer-utils.test.js +69 -0
- package/cjs/utils/buffer-utils.test.js.map +1 -0
- package/cjs/utils/condition-variable.test.d.ts +1 -0
- package/cjs/utils/condition-variable.test.js +27 -0
- package/cjs/utils/condition-variable.test.js.map +1 -0
- package/cjs/utils/controllable-promise.test.d.ts +1 -0
- package/cjs/utils/controllable-promise.test.js +17 -0
- package/cjs/utils/controllable-promise.test.js.map +1 -0
- package/cjs/utils/crypto/keys.test.d.ts +1 -0
- package/cjs/utils/crypto/keys.test.js +40 -0
- package/cjs/utils/crypto/keys.test.js.map +1 -0
- package/cjs/utils/crypto/miller-rabin.test.d.ts +1 -0
- package/cjs/utils/crypto/miller-rabin.test.js +60 -0
- package/cjs/utils/crypto/miller-rabin.test.js.map +1 -0
- package/cjs/utils/crypto/mtproto.test.d.ts +1 -0
- package/cjs/utils/crypto/mtproto.test.js +47 -0
- package/cjs/utils/crypto/mtproto.test.js.map +1 -0
- package/cjs/utils/crypto/node.test.d.ts +1 -0
- package/cjs/utils/crypto/node.test.js +13 -0
- package/cjs/utils/crypto/node.test.js.map +1 -0
- package/cjs/utils/crypto/password.test.d.ts +1 -0
- package/cjs/utils/crypto/password.test.js +95 -0
- package/cjs/utils/crypto/password.test.js.map +1 -0
- package/cjs/utils/crypto/utils.test.d.ts +1 -0
- package/cjs/utils/crypto/utils.test.js +49 -0
- package/cjs/utils/crypto/utils.test.js.map +1 -0
- package/cjs/utils/crypto/web.test.d.ts +1 -0
- package/cjs/utils/crypto/web.test.js +17 -0
- package/cjs/utils/crypto/web.test.js.map +1 -0
- package/cjs/utils/deque.test.d.ts +1 -0
- package/cjs/utils/deque.test.js +128 -0
- package/cjs/utils/deque.test.js.map +1 -0
- package/cjs/utils/function-utils.test.d.ts +1 -0
- package/cjs/utils/function-utils.test.js +23 -0
- package/cjs/utils/function-utils.test.js.map +1 -0
- package/cjs/utils/linked-list.test.d.ts +1 -0
- package/cjs/utils/linked-list.test.js +36 -0
- package/cjs/utils/linked-list.test.js.map +1 -0
- package/cjs/utils/links/bots.test.d.ts +1 -0
- package/cjs/utils/links/bots.test.js +152 -0
- package/cjs/utils/links/bots.test.js.map +1 -0
- package/cjs/utils/links/chat.test.d.ts +1 -0
- package/cjs/utils/links/chat.test.js +84 -0
- package/cjs/utils/links/chat.test.js.map +1 -0
- package/cjs/utils/links/misc.test.d.ts +1 -0
- package/cjs/utils/links/misc.test.js +153 -0
- package/cjs/utils/links/misc.test.js.map +1 -0
- package/cjs/utils/links/proxy.test.d.ts +1 -0
- package/cjs/utils/links/proxy.test.js +74 -0
- package/cjs/utils/links/proxy.test.js.map +1 -0
- package/cjs/utils/links/user.test.d.ts +1 -0
- package/cjs/utils/links/user.test.js +63 -0
- package/cjs/utils/links/user.test.js.map +1 -0
- package/cjs/utils/logger.test.d.ts +1 -0
- package/cjs/utils/logger.test.js +125 -0
- package/cjs/utils/logger.test.js.map +1 -0
- package/cjs/utils/long-utils.test.d.ts +1 -0
- package/cjs/utils/long-utils.test.js +158 -0
- package/cjs/utils/long-utils.test.js.map +1 -0
- package/cjs/utils/lru-map.test.d.ts +1 -0
- package/cjs/utils/lru-map.test.js +96 -0
- package/cjs/utils/lru-map.test.js.map +1 -0
- package/cjs/utils/lru-set.test.d.ts +1 -0
- package/cjs/utils/lru-set.test.js +77 -0
- package/cjs/utils/lru-set.test.js.map +1 -0
- package/cjs/utils/peer-utils.test.d.ts +1 -0
- package/cjs/utils/peer-utils.test.js +122 -0
- package/cjs/utils/peer-utils.test.js.map +1 -0
- package/cjs/utils/sorted-array.test.d.ts +1 -0
- package/cjs/utils/sorted-array.test.js +66 -0
- package/cjs/utils/sorted-array.test.js.map +1 -0
- package/cjs/utils/string-session.test.d.ts +1 -0
- package/cjs/utils/string-session.test.js +106 -0
- package/cjs/utils/string-session.test.js.map +1 -0
- package/cjs/utils/tl-json.test.d.ts +1 -0
- package/cjs/utils/tl-json.test.js +83 -0
- package/cjs/utils/tl-json.test.js.map +1 -0
- package/cjs/utils/type-assertions.test.d.ts +1 -0
- package/cjs/utils/type-assertions.test.js +67 -0
- package/cjs/utils/type-assertions.test.js.map +1 -0
- package/esm/network/auth-key.test.d.ts +1 -0
- package/esm/network/auth-key.test.js +106 -0
- package/esm/network/auth-key.test.js.map +1 -0
- package/esm/network/config-manager.js +2 -1
- package/esm/network/config-manager.js.map +1 -1
- package/esm/network/config-manager.test.d.ts +1 -0
- package/esm/network/config-manager.test.js +168 -0
- package/esm/network/config-manager.test.js.map +1 -0
- package/esm/network/network-manager.js +1 -1
- package/esm/network/persistent-connection.test.d.ts +1 -0
- package/esm/network/persistent-connection.test.js +155 -0
- package/esm/network/persistent-connection.test.js.map +1 -0
- package/esm/network/session-connection.js +3 -2
- package/esm/network/session-connection.js.map +1 -1
- package/esm/network/transports/intermediate.test.d.ts +1 -0
- package/esm/network/transports/intermediate.test.js +84 -0
- package/esm/network/transports/intermediate.test.js.map +1 -0
- package/esm/network/transports/obfuscated.js +1 -1
- package/esm/network/transports/obfuscated.js.map +1 -1
- package/esm/network/transports/obfuscated.test.d.ts +1 -0
- package/esm/network/transports/obfuscated.test.js +129 -0
- package/esm/network/transports/obfuscated.test.js.map +1 -0
- package/esm/network/transports/tcp.js +1 -1
- package/esm/network/transports/tcp.js.map +1 -1
- package/esm/network/transports/tcp.test.d.ts +1 -0
- package/esm/network/transports/tcp.test.js +95 -0
- package/esm/network/transports/tcp.test.js.map +1 -0
- package/esm/network/transports/websocket.test.d.ts +1 -0
- package/esm/network/transports/websocket.test.js +89 -0
- package/esm/network/transports/websocket.test.js.map +1 -0
- package/esm/storage/json.test.d.ts +1 -0
- package/esm/storage/json.test.js +35 -0
- package/esm/storage/json.test.js.map +1 -0
- package/esm/storage/localstorage.test.d.ts +1 -0
- package/esm/storage/localstorage.test.js +21 -0
- package/esm/storage/localstorage.test.js.map +1 -0
- package/esm/storage/memory.test.d.ts +1 -0
- package/esm/storage/memory.test.js +45 -0
- package/esm/storage/memory.test.js.map +1 -0
- package/esm/utils/async-lock.test.d.ts +1 -0
- package/esm/utils/async-lock.test.js +23 -0
- package/esm/utils/async-lock.test.js.map +1 -0
- package/esm/utils/bigint-utils.test.d.ts +1 -0
- package/esm/utils/bigint-utils.test.js +148 -0
- package/esm/utils/bigint-utils.test.js.map +1 -0
- package/esm/utils/buffer-utils.test.d.ts +1 -0
- package/esm/utils/buffer-utils.test.js +67 -0
- package/esm/utils/buffer-utils.test.js.map +1 -0
- package/esm/utils/condition-variable.test.d.ts +1 -0
- package/esm/utils/condition-variable.test.js +25 -0
- package/esm/utils/condition-variable.test.js.map +1 -0
- package/esm/utils/controllable-promise.test.d.ts +1 -0
- package/esm/utils/controllable-promise.test.js +15 -0
- package/esm/utils/controllable-promise.test.js.map +1 -0
- package/esm/utils/crypto/keys.test.d.ts +1 -0
- package/esm/utils/crypto/keys.test.js +38 -0
- package/esm/utils/crypto/keys.test.js.map +1 -0
- package/esm/utils/crypto/miller-rabin.test.d.ts +1 -0
- package/esm/utils/crypto/miller-rabin.test.js +58 -0
- package/esm/utils/crypto/miller-rabin.test.js.map +1 -0
- package/esm/utils/crypto/mtproto.test.d.ts +1 -0
- package/esm/utils/crypto/mtproto.test.js +45 -0
- package/esm/utils/crypto/mtproto.test.js.map +1 -0
- package/esm/utils/crypto/node.test.d.ts +1 -0
- package/esm/utils/crypto/node.test.js +11 -0
- package/esm/utils/crypto/node.test.js.map +1 -0
- package/esm/utils/crypto/password.test.d.ts +1 -0
- package/esm/utils/crypto/password.test.js +90 -0
- package/esm/utils/crypto/password.test.js.map +1 -0
- package/esm/utils/crypto/utils.test.d.ts +1 -0
- package/esm/utils/crypto/utils.test.js +47 -0
- package/esm/utils/crypto/utils.test.js.map +1 -0
- package/esm/utils/crypto/web.test.d.ts +1 -0
- package/esm/utils/crypto/web.test.js +15 -0
- package/esm/utils/crypto/web.test.js.map +1 -0
- package/esm/utils/deque.test.d.ts +1 -0
- package/esm/utils/deque.test.js +126 -0
- package/esm/utils/deque.test.js.map +1 -0
- package/esm/utils/function-utils.test.d.ts +1 -0
- package/esm/utils/function-utils.test.js +21 -0
- package/esm/utils/function-utils.test.js.map +1 -0
- package/esm/utils/linked-list.test.d.ts +1 -0
- package/esm/utils/linked-list.test.js +34 -0
- package/esm/utils/linked-list.test.js.map +1 -0
- package/esm/utils/links/bots.test.d.ts +1 -0
- package/esm/utils/links/bots.test.js +150 -0
- package/esm/utils/links/bots.test.js.map +1 -0
- package/esm/utils/links/chat.test.d.ts +1 -0
- package/esm/utils/links/chat.test.js +82 -0
- package/esm/utils/links/chat.test.js.map +1 -0
- package/esm/utils/links/misc.test.d.ts +1 -0
- package/esm/utils/links/misc.test.js +151 -0
- package/esm/utils/links/misc.test.js.map +1 -0
- package/esm/utils/links/proxy.test.d.ts +1 -0
- package/esm/utils/links/proxy.test.js +72 -0
- package/esm/utils/links/proxy.test.js.map +1 -0
- package/esm/utils/links/user.test.d.ts +1 -0
- package/esm/utils/links/user.test.js +61 -0
- package/esm/utils/links/user.test.js.map +1 -0
- package/esm/utils/logger.test.d.ts +1 -0
- package/esm/utils/logger.test.js +120 -0
- package/esm/utils/logger.test.js.map +1 -0
- package/esm/utils/long-utils.test.d.ts +1 -0
- package/esm/utils/long-utils.test.js +153 -0
- package/esm/utils/long-utils.test.js.map +1 -0
- package/esm/utils/lru-map.test.d.ts +1 -0
- package/esm/utils/lru-map.test.js +94 -0
- package/esm/utils/lru-map.test.js.map +1 -0
- package/esm/utils/lru-set.test.d.ts +1 -0
- package/esm/utils/lru-set.test.js +72 -0
- package/esm/utils/lru-set.test.js.map +1 -0
- package/esm/utils/peer-utils.test.d.ts +1 -0
- package/esm/utils/peer-utils.test.js +117 -0
- package/esm/utils/peer-utils.test.js.map +1 -0
- package/esm/utils/sorted-array.test.d.ts +1 -0
- package/esm/utils/sorted-array.test.js +64 -0
- package/esm/utils/sorted-array.test.js.map +1 -0
- package/esm/utils/string-session.test.d.ts +1 -0
- package/esm/utils/string-session.test.js +104 -0
- package/esm/utils/string-session.test.js.map +1 -0
- package/esm/utils/tl-json.test.d.ts +1 -0
- package/esm/utils/tl-json.test.js +81 -0
- package/esm/utils/tl-json.test.js.map +1 -0
- package/esm/utils/type-assertions.test.d.ts +1 -0
- package/esm/utils/type-assertions.test.js +65 -0
- package/esm/utils/type-assertions.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const long_1 = __importDefault(require("long"));
|
|
7
|
+
const vitest_1 = require("vitest");
|
|
8
|
+
const test_1 = require("@mtcute/test");
|
|
9
|
+
const tl_runtime_1 = require("@mtcute/tl-runtime");
|
|
10
|
+
const index_js_1 = require("../utils/index.js");
|
|
11
|
+
const auth_key_js_1 = require("./auth-key.js");
|
|
12
|
+
const authKey = new Uint8Array(256);
|
|
13
|
+
for (let i = 0; i < 256; i += 32) {
|
|
14
|
+
(0, tl_runtime_1.hexDecode)(authKey.subarray(i, i + 32), '98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0');
|
|
15
|
+
}
|
|
16
|
+
(0, vitest_1.describe)('AuthKey', () => {
|
|
17
|
+
async function create() {
|
|
18
|
+
const logger = new index_js_1.LogManager();
|
|
19
|
+
const readerMap = {};
|
|
20
|
+
const crypto = await (0, test_1.defaultTestCryptoProvider)();
|
|
21
|
+
const key = new auth_key_js_1.AuthKey(crypto, logger, readerMap);
|
|
22
|
+
key.setup(authKey);
|
|
23
|
+
return key;
|
|
24
|
+
}
|
|
25
|
+
const msgId = long_1.default.fromBits(0xbeef1234, 0x1234beef, true);
|
|
26
|
+
const seqNo = 777;
|
|
27
|
+
const serverSalt = long_1.default.fromBits(0xdeadbeef, 0xbeefdead);
|
|
28
|
+
const sessionId = long_1.default.fromBits(0xfeedbeef, 0xbeeffeed);
|
|
29
|
+
function writeMessage(body) {
|
|
30
|
+
const buf = new Uint8Array(16 + body.length);
|
|
31
|
+
const dv = new DataView(buf.buffer);
|
|
32
|
+
dv.setInt32(0, msgId.low, true);
|
|
33
|
+
dv.setInt32(4, msgId.high, true);
|
|
34
|
+
dv.setInt32(8, seqNo, true);
|
|
35
|
+
dv.setInt32(12, body.length, true);
|
|
36
|
+
buf.set(body, 16);
|
|
37
|
+
return buf;
|
|
38
|
+
}
|
|
39
|
+
(0, vitest_1.it)('should calculate derivatives', async () => {
|
|
40
|
+
const key = await create();
|
|
41
|
+
(0, vitest_1.expect)((0, tl_runtime_1.hexEncode)(key.key)).toEqual((0, tl_runtime_1.hexEncode)(authKey));
|
|
42
|
+
(0, vitest_1.expect)((0, tl_runtime_1.hexEncode)(key.clientSalt)).toEqual('f73c3622dec230e098cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4b');
|
|
43
|
+
(0, vitest_1.expect)((0, tl_runtime_1.hexEncode)(key.serverSalt)).toEqual('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0');
|
|
44
|
+
(0, vitest_1.expect)((0, tl_runtime_1.hexEncode)(key.id)).toEqual('40fa5bb7cb56a895');
|
|
45
|
+
});
|
|
46
|
+
(0, vitest_1.it)('should encrypt a message', async () => {
|
|
47
|
+
const message = writeMessage((0, tl_runtime_1.utf8EncodeToBuffer)('hello, world!!!!'));
|
|
48
|
+
const key = await create();
|
|
49
|
+
const msg = key.encryptMessage(message, serverSalt, sessionId);
|
|
50
|
+
(0, vitest_1.expect)((0, tl_runtime_1.hexEncode)(msg)).toEqual('40fa5bb7cb56a895f6f5a88914892aadf87c68031cc953ba29d68e118021f329' +
|
|
51
|
+
'be386a620d49f3ad3a50c60dcef3733f214e8cefa3e403c11d193637d4971dc1' +
|
|
52
|
+
'5db7f74b26fd16cb0e8fee30bf7e3f68858fe82927e2cd06');
|
|
53
|
+
});
|
|
54
|
+
(0, vitest_1.describe)('decrypt', () => {
|
|
55
|
+
async function decrypt(message) {
|
|
56
|
+
const key = await create();
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
// in this method, errors are not thrown but rather logged
|
|
59
|
+
vitest_1.vi.spyOn(key.log, 'warn').mockImplementation((msg, ...fmt) => reject(`${msg} : ${fmt.map((it) => JSON.stringify(it)).join(' ')}`));
|
|
60
|
+
key.decryptMessage(message, sessionId, (...args) => resolve(args));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
(0, vitest_1.it)('should decrypt a message', async () => {
|
|
64
|
+
const message = (0, tl_runtime_1.hexDecodeToBuffer)('40fa5bb7cb56a8950c394b884f1529efc42fea22d972fea650a714ce6d2d1bdb' +
|
|
65
|
+
'3d98ff5929b8768c401771a69795f36a7e720dcafac2efbccd0ba368e8a7f48b' +
|
|
66
|
+
'07362cac1a32ffcabe188b51a36cc4d54e1d0633cf9eaf35');
|
|
67
|
+
const [decMsgId, decSeqNo, data] = await decrypt(message);
|
|
68
|
+
(0, vitest_1.expect)(decMsgId).toEqual(msgId);
|
|
69
|
+
(0, vitest_1.expect)(decSeqNo).toEqual(seqNo);
|
|
70
|
+
(0, vitest_1.expect)((0, tl_runtime_1.utf8Decode)(data.raw(16))).toEqual('hello, world!!!!');
|
|
71
|
+
});
|
|
72
|
+
(0, vitest_1.it)('should decrypt a message with padding', async () => {
|
|
73
|
+
const message = (0, tl_runtime_1.hexDecodeToBuffer)('40fa5bb7cb56a8950c394b884f1529efc42fea22d972fea650a714ce6d2d1bdb' +
|
|
74
|
+
'3d98ff5929b8768c401771a69795f36a7e720dcafac2efbccd0ba368e8a7f48b' +
|
|
75
|
+
'07362cac1a32ffcabe188b51a36cc4d54e1d0633cf9eaf35' +
|
|
76
|
+
'deadbeef');
|
|
77
|
+
const [decMsgId, decSeqNo, data] = await decrypt(message);
|
|
78
|
+
(0, vitest_1.expect)(decMsgId).toEqual(msgId);
|
|
79
|
+
(0, vitest_1.expect)(decSeqNo).toEqual(seqNo);
|
|
80
|
+
(0, vitest_1.expect)((0, tl_runtime_1.utf8Decode)(data.raw(16))).toEqual('hello, world!!!!');
|
|
81
|
+
});
|
|
82
|
+
(0, vitest_1.it)('should ignore messages with invalid message key', async () => {
|
|
83
|
+
const message = (0, tl_runtime_1.hexDecodeToBuffer)('40fa5bb7cb56a8950000000000000000000000000000000050a714ce6d2d1bdb' +
|
|
84
|
+
'3d98ff5929b8768c401771a69795f36a7e720dcafac2efbccd0ba368e8a7f48b' +
|
|
85
|
+
'07362cac1a32ffcabe188b51a36cc4d54e1d0633cf9eaf35');
|
|
86
|
+
await (0, vitest_1.expect)(() => decrypt(message)).rejects.toThrow('message with invalid messageKey');
|
|
87
|
+
});
|
|
88
|
+
(0, vitest_1.it)('should ignore messages with invalid session_id', async () => {
|
|
89
|
+
const message = (0, tl_runtime_1.hexDecodeToBuffer)('40fa5bb7cb56a895a986a7e97f4e90aa2769b5e702c6e86f5e1e82c6ff0c6829' +
|
|
90
|
+
'2521a2ba9704fa37fb341d895cf32662c6cf47ba31cbf27c30d5c03f6c2930f4' +
|
|
91
|
+
'30fd8858b836b73fe32d4a95b8ebcdbc9ca8908f7964c40a');
|
|
92
|
+
await (0, vitest_1.expect)(() => decrypt(message)).rejects.toThrow('message with invalid sessionId');
|
|
93
|
+
});
|
|
94
|
+
(0, vitest_1.it)('should ignore messages with invalid length', async () => {
|
|
95
|
+
const messageTooLong = (0, tl_runtime_1.hexDecodeToBuffer)('40fa5bb7cb56a8950d19412233dd5d24be697c73274e08fbe515cf65e0c5f70c' +
|
|
96
|
+
'ad75fd2badc18c9f999f287351144eeb1cfcaa9bea33ef5058999ad96a498306' +
|
|
97
|
+
'08d2859425685a55b21fab413bfabc42ec5da283853b28c0');
|
|
98
|
+
const messageUnaligned = (0, tl_runtime_1.hexDecodeToBuffer)('40fa5bb7cb56a8957b4e4bec561eee4a5a1025bc8a35d3d0c79a3685d2b90ff0' +
|
|
99
|
+
'5f638e9c42c9fd9448b0ce8e7d49e7ea1ce458e47b825b5c7fd8ddf5b4fded46' +
|
|
100
|
+
'2a4bcc02f3ff2e89de6764d6d219f575e457fdcf8c163cdf');
|
|
101
|
+
await (0, vitest_1.expect)(() => decrypt(messageTooLong)).rejects.toThrow('message with invalid length: %d > %d');
|
|
102
|
+
await (0, vitest_1.expect)(() => decrypt(messageUnaligned)).rejects.toThrow('message with invalid length: %d is not a multiple of 4');
|
|
103
|
+
});
|
|
104
|
+
(0, vitest_1.it)('should ignore messages with invalid padding', async () => {
|
|
105
|
+
const message = (0, tl_runtime_1.hexDecodeToBuffer)('40fa5bb7cb56a895133671d1c637a9836e2c64b4d1a0521d8a25a6416fd4dc9e' +
|
|
106
|
+
'79f9478fb837703cc9efa0a19d12143c2a26e57cb4bc64d7bc972dd8f19c53c590cc258162f44afc');
|
|
107
|
+
await (0, vitest_1.expect)(() => decrypt(message)).rejects.toThrow('message with invalid padding size');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
//# sourceMappingURL=auth-key.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-key.test.js","sourceRoot":"","sources":["../../../src/network/auth-key.test.ts"],"names":[],"mappings":"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","sourcesContent":["import Long from 'long'\nimport { describe, expect, it, vi } from 'vitest'\n\nimport { defaultTestCryptoProvider } from '@mtcute/test'\nimport {\n hexDecode,\n hexDecodeToBuffer,\n hexEncode,\n TlBinaryReader,\n TlReaderMap,\n utf8Decode,\n utf8EncodeToBuffer,\n} from '@mtcute/tl-runtime'\n\nimport { LogManager } from '../utils/index.js'\nimport { AuthKey } from './auth-key.js'\n\nconst authKey = new Uint8Array(256)\n\nfor (let i = 0; i < 256; i += 32) {\n hexDecode(authKey.subarray(i, i + 32), '98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0')\n}\n\ndescribe('AuthKey', () => {\n async function create() {\n const logger = new LogManager()\n const readerMap: TlReaderMap = {}\n const crypto = await defaultTestCryptoProvider()\n\n const key = new AuthKey(crypto, logger, readerMap)\n key.setup(authKey)\n\n return key\n }\n\n const msgId = Long.fromBits(0xbeef1234, 0x1234beef, true)\n const seqNo = 777\n const serverSalt = Long.fromBits(0xdeadbeef, 0xbeefdead)\n const sessionId = Long.fromBits(0xfeedbeef, 0xbeeffeed)\n\n function writeMessage(body: Uint8Array) {\n const buf = new Uint8Array(16 + body.length)\n const dv = new DataView(buf.buffer)\n\n dv.setInt32(0, msgId.low, true)\n dv.setInt32(4, msgId.high, true)\n dv.setInt32(8, seqNo, true)\n dv.setInt32(12, body.length, true)\n buf.set(body, 16)\n\n return buf\n }\n\n it('should calculate derivatives', async () => {\n const key = await create()\n\n expect(hexEncode(key.key)).toEqual(hexEncode(authKey))\n expect(hexEncode(key.clientSalt)).toEqual('f73c3622dec230e098cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4b')\n expect(hexEncode(key.serverSalt)).toEqual('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0')\n expect(hexEncode(key.id)).toEqual('40fa5bb7cb56a895')\n })\n\n it('should encrypt a message', async () => {\n const message = writeMessage(utf8EncodeToBuffer('hello, world!!!!'))\n\n const key = await create()\n const msg = key.encryptMessage(message, serverSalt, sessionId)\n\n expect(hexEncode(msg)).toEqual(\n '40fa5bb7cb56a895f6f5a88914892aadf87c68031cc953ba29d68e118021f329' +\n 'be386a620d49f3ad3a50c60dcef3733f214e8cefa3e403c11d193637d4971dc1' +\n '5db7f74b26fd16cb0e8fee30bf7e3f68858fe82927e2cd06',\n )\n })\n\n describe('decrypt', () => {\n async function decrypt(message: Uint8Array) {\n const key = await create()\n\n return new Promise<[Long, number, TlBinaryReader]>((resolve, reject) => {\n // in this method, errors are not thrown but rather logged\n vi.spyOn(key.log, 'warn').mockImplementation((msg, ...fmt) =>\n reject(`${msg} : ${fmt.map((it) => JSON.stringify(it)).join(' ')}`),\n )\n\n key.decryptMessage(message, sessionId, (...args) => resolve(args))\n })\n }\n\n it('should decrypt a message', async () => {\n const message = hexDecodeToBuffer(\n '40fa5bb7cb56a8950c394b884f1529efc42fea22d972fea650a714ce6d2d1bdb' +\n '3d98ff5929b8768c401771a69795f36a7e720dcafac2efbccd0ba368e8a7f48b' +\n '07362cac1a32ffcabe188b51a36cc4d54e1d0633cf9eaf35',\n )\n\n const [decMsgId, decSeqNo, data] = await decrypt(message)\n\n expect(decMsgId).toEqual(msgId)\n expect(decSeqNo).toEqual(seqNo)\n expect(utf8Decode(data.raw(16))).toEqual('hello, world!!!!')\n })\n\n it('should decrypt a message with padding', async () => {\n const message = hexDecodeToBuffer(\n '40fa5bb7cb56a8950c394b884f1529efc42fea22d972fea650a714ce6d2d1bdb' +\n '3d98ff5929b8768c401771a69795f36a7e720dcafac2efbccd0ba368e8a7f48b' +\n '07362cac1a32ffcabe188b51a36cc4d54e1d0633cf9eaf35' +\n 'deadbeef', // some padding (e.g. from padded transport),\n )\n\n const [decMsgId, decSeqNo, data] = await decrypt(message)\n\n expect(decMsgId).toEqual(msgId)\n expect(decSeqNo).toEqual(seqNo)\n expect(utf8Decode(data.raw(16))).toEqual('hello, world!!!!')\n })\n\n it('should ignore messages with invalid message key', async () => {\n const message = hexDecodeToBuffer(\n '40fa5bb7cb56a8950000000000000000000000000000000050a714ce6d2d1bdb' +\n '3d98ff5929b8768c401771a69795f36a7e720dcafac2efbccd0ba368e8a7f48b' +\n '07362cac1a32ffcabe188b51a36cc4d54e1d0633cf9eaf35',\n )\n\n await expect(() => decrypt(message)).rejects.toThrow('message with invalid messageKey')\n })\n\n it('should ignore messages with invalid session_id', async () => {\n const message = hexDecodeToBuffer(\n '40fa5bb7cb56a895a986a7e97f4e90aa2769b5e702c6e86f5e1e82c6ff0c6829' +\n '2521a2ba9704fa37fb341d895cf32662c6cf47ba31cbf27c30d5c03f6c2930f4' +\n '30fd8858b836b73fe32d4a95b8ebcdbc9ca8908f7964c40a',\n )\n\n await expect(() => decrypt(message)).rejects.toThrow('message with invalid sessionId')\n })\n\n it('should ignore messages with invalid length', async () => {\n const messageTooLong = hexDecodeToBuffer(\n '40fa5bb7cb56a8950d19412233dd5d24be697c73274e08fbe515cf65e0c5f70c' +\n 'ad75fd2badc18c9f999f287351144eeb1cfcaa9bea33ef5058999ad96a498306' +\n '08d2859425685a55b21fab413bfabc42ec5da283853b28c0',\n )\n const messageUnaligned = hexDecodeToBuffer(\n '40fa5bb7cb56a8957b4e4bec561eee4a5a1025bc8a35d3d0c79a3685d2b90ff0' +\n '5f638e9c42c9fd9448b0ce8e7d49e7ea1ce458e47b825b5c7fd8ddf5b4fded46' +\n '2a4bcc02f3ff2e89de6764d6d219f575e457fdcf8c163cdf',\n )\n\n await expect(() => decrypt(messageTooLong)).rejects.toThrow('message with invalid length: %d > %d')\n await expect(() => decrypt(messageUnaligned)).rejects.toThrow(\n 'message with invalid length: %d is not a multiple of 4',\n )\n })\n\n it('should ignore messages with invalid padding', async () => {\n const message = hexDecodeToBuffer(\n '40fa5bb7cb56a895133671d1c637a9836e2c64b4d1a0521d8a25a6416fd4dc9e' +\n '79f9478fb837703cc9efa0a19d12143c2a26e57cb4bc64d7bc972dd8f19c53c590cc258162f44afc',\n )\n\n await expect(() => decrypt(message)).rejects.toThrow('message with invalid padding size')\n })\n })\n})\n"]}
|
|
@@ -14,7 +14,7 @@ class ConfigManager {
|
|
|
14
14
|
this._listeners = [];
|
|
15
15
|
}
|
|
16
16
|
get isStale() {
|
|
17
|
-
return !this._config || this._config.expires
|
|
17
|
+
return !this._config || this._config.expires <= Date.now() / 1000;
|
|
18
18
|
}
|
|
19
19
|
update(force = false) {
|
|
20
20
|
if (!force && !this.isStale)
|
|
@@ -24,6 +24,7 @@ class ConfigManager {
|
|
|
24
24
|
return (this._updatingPromise = this._update().then((config) => {
|
|
25
25
|
if (this._destroyed)
|
|
26
26
|
return;
|
|
27
|
+
this._updatingPromise = undefined;
|
|
27
28
|
this.setConfig(config);
|
|
28
29
|
}));
|
|
29
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../../src/network/config-manager.ts"],"names":[],"mappings":";;;AAEA;;;;;GAKG;AACH,MAAa,aAAa;IACtB,YAAoB,OAAoC;QAApC,YAAO,GAAP,OAAO,CAA6B;QAEhD,eAAU,GAAG,KAAK,CAAA;QAOlB,eAAU,GAAuC,EAAE,CAAA;IATA,CAAC;IAW5D,IAAI,OAAO;QACP,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../../src/network/config-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { tl } from '@mtcute/tl'\n\n/**\n * Config manager is responsible for keeping\n * the current server configuration up-to-date\n * and providing methods to find the best DC\n * option for the current session.\n */\nexport class ConfigManager {\n constructor(private _update: () => Promise<tl.RawConfig>) {}\n\n private _destroyed = false\n private _config?: tl.RawConfig\n private _cdnConfig?: tl.RawCdnConfig\n\n private _updateTimeout?: NodeJS.Timeout\n private _updatingPromise?: Promise<void>\n\n private _listeners: ((config: tl.RawConfig) => void)[] = []\n\n get isStale(): boolean {\n return !this._config || this._config.expires <= Date.now() / 1000\n }\n\n update(force = false): Promise<void> {\n if (!force && !this.isStale) return Promise.resolve()\n if (this._updatingPromise) return this._updatingPromise\n\n return (this._updatingPromise = this._update().then((config) => {\n if (this._destroyed) return\n this._updatingPromise = undefined\n\n this.setConfig(config)\n }))\n }\n\n setConfig(config: tl.RawConfig): void {\n this._config = config\n\n if (this._updateTimeout) clearTimeout(this._updateTimeout)\n this._updateTimeout = setTimeout(\n () => void this.update().catch(() => {}),\n (config.expires - Date.now() / 1000) * 1000,\n )\n\n for (const cb of this._listeners) cb(config)\n }\n\n onConfigUpdate(cb: (config: tl.RawConfig) => void): void {\n this._listeners.push(cb)\n }\n\n offConfigUpdate(cb: (config: tl.RawConfig) => void): void {\n const idx = this._listeners.indexOf(cb)\n if (idx >= 0) this._listeners.splice(idx, 1)\n }\n\n getNow(): tl.RawConfig | undefined {\n return this._config\n }\n\n async get(): Promise<tl.RawConfig> {\n if (this.isStale) await this.update()\n\n return this._config!\n }\n\n destroy(): void {\n if (this._updateTimeout) clearTimeout(this._updateTimeout)\n this._listeners.length = 0\n this._destroyed = true\n }\n\n async findOption(params: {\n dcId: number\n allowIpv6?: boolean\n preferIpv6?: boolean\n allowMedia?: boolean\n preferMedia?: boolean\n cdn?: boolean\n }): Promise<tl.RawDcOption | undefined> {\n if (this.isStale) await this.update()\n\n const options = this._config!.dcOptions.filter((opt) => {\n if (opt.tcpoOnly) return false // unsupported\n if (opt.ipv6 && !params.allowIpv6) return false\n if (opt.mediaOnly && !params.allowMedia) return false\n if (opt.cdn && !params.cdn) return false\n\n return opt.id === params.dcId\n })\n\n if (params.preferMedia && params.preferIpv6) {\n const r = options.find((opt) => opt.mediaOnly && opt.ipv6)\n if (r) return r\n }\n\n if (params.preferMedia) {\n const r = options.find((opt) => opt.mediaOnly)\n if (r) return r\n }\n\n if (params.preferIpv6) {\n const r = options.find((opt) => opt.ipv6)\n if (r) return r\n }\n\n return options[0]\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const test_1 = require("@mtcute/test");
|
|
5
|
+
const config_manager_js_1 = require("./config-manager.js");
|
|
6
|
+
(0, vitest_1.describe)('ConfigManager', () => {
|
|
7
|
+
const config = (0, test_1.createStub)('config', {
|
|
8
|
+
expires: 300,
|
|
9
|
+
});
|
|
10
|
+
const getConfig = vitest_1.vi.fn();
|
|
11
|
+
(0, vitest_1.beforeEach)(() => {
|
|
12
|
+
vitest_1.vi.useFakeTimers();
|
|
13
|
+
vitest_1.vi.setSystemTime(0);
|
|
14
|
+
getConfig.mockClear().mockImplementation(() => Promise.resolve(config));
|
|
15
|
+
});
|
|
16
|
+
(0, vitest_1.afterEach)(() => void vitest_1.vi.useRealTimers());
|
|
17
|
+
(0, vitest_1.it)('should fetch initial config', async () => {
|
|
18
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
19
|
+
const fetchedConfig = await cm.get();
|
|
20
|
+
(0, vitest_1.expect)(getConfig).toHaveBeenCalledTimes(1);
|
|
21
|
+
(0, vitest_1.expect)(fetchedConfig).toEqual(config);
|
|
22
|
+
(0, vitest_1.expect)(cm.getNow()).toEqual(config);
|
|
23
|
+
});
|
|
24
|
+
(0, vitest_1.it)('should automatically update config', async () => {
|
|
25
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
26
|
+
await cm.update();
|
|
27
|
+
getConfig.mockImplementation(() => Promise.resolve({
|
|
28
|
+
...config,
|
|
29
|
+
expires: 600,
|
|
30
|
+
}));
|
|
31
|
+
await vitest_1.vi.advanceTimersByTimeAsync(301000);
|
|
32
|
+
(0, vitest_1.expect)(getConfig).toHaveBeenCalledTimes(2);
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.it)('should correctly determine stale config', () => {
|
|
35
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
36
|
+
(0, vitest_1.expect)(cm.isStale).toBe(true);
|
|
37
|
+
cm.setConfig(config);
|
|
38
|
+
(0, vitest_1.expect)(cm.isStale).toBe(false);
|
|
39
|
+
vitest_1.vi.setSystemTime(300000);
|
|
40
|
+
(0, vitest_1.expect)(cm.isStale).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
(0, vitest_1.it)('should not update config if not stale', async () => {
|
|
43
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
44
|
+
await cm.update();
|
|
45
|
+
getConfig.mockClear();
|
|
46
|
+
await cm.update();
|
|
47
|
+
(0, vitest_1.expect)(getConfig).not.toHaveBeenCalled();
|
|
48
|
+
});
|
|
49
|
+
(0, vitest_1.it)('should not update config twice', async () => {
|
|
50
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
51
|
+
await cm.update();
|
|
52
|
+
vitest_1.vi.setSystemTime(300000);
|
|
53
|
+
getConfig.mockClear();
|
|
54
|
+
await Promise.all([cm.update(), cm.update()]);
|
|
55
|
+
(0, vitest_1.expect)(getConfig).toHaveBeenCalledOnce();
|
|
56
|
+
});
|
|
57
|
+
(0, vitest_1.it)('should call listeners on config update', async () => {
|
|
58
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
59
|
+
const listener = vitest_1.vi.fn();
|
|
60
|
+
cm.onConfigUpdate(listener);
|
|
61
|
+
await cm.update();
|
|
62
|
+
vitest_1.vi.setSystemTime(300000);
|
|
63
|
+
cm.offConfigUpdate(listener);
|
|
64
|
+
await cm.update();
|
|
65
|
+
(0, vitest_1.expect)(listener).toHaveBeenCalledOnce();
|
|
66
|
+
(0, vitest_1.expect)(listener).toHaveBeenCalledWith(config);
|
|
67
|
+
});
|
|
68
|
+
(0, vitest_1.it)('should correctly destroy', async () => {
|
|
69
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
70
|
+
await cm.update();
|
|
71
|
+
cm.destroy();
|
|
72
|
+
getConfig.mockClear();
|
|
73
|
+
await vitest_1.vi.advanceTimersByTimeAsync(301000);
|
|
74
|
+
(0, vitest_1.expect)(getConfig).not.toHaveBeenCalled();
|
|
75
|
+
});
|
|
76
|
+
(0, vitest_1.describe)('findOption', () => {
|
|
77
|
+
const useDcOptions = (options) => {
|
|
78
|
+
getConfig.mockImplementation(() => Promise.resolve({
|
|
79
|
+
...config,
|
|
80
|
+
dcOptions: options,
|
|
81
|
+
}));
|
|
82
|
+
};
|
|
83
|
+
const findOption = async (params) => {
|
|
84
|
+
const cm = new config_manager_js_1.ConfigManager(getConfig);
|
|
85
|
+
await cm.update();
|
|
86
|
+
return cm.findOption(params);
|
|
87
|
+
};
|
|
88
|
+
(0, vitest_1.it)('should find option by dc id', async () => {
|
|
89
|
+
useDcOptions([
|
|
90
|
+
(0, test_1.createStub)('dcOption', { id: 1, ipAddress: '1.1.1.1' }),
|
|
91
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '2.2.2.2' }),
|
|
92
|
+
]);
|
|
93
|
+
(0, vitest_1.expect)(await findOption({ dcId: 1 })).toMatchObject({
|
|
94
|
+
id: 1,
|
|
95
|
+
ipAddress: '1.1.1.1',
|
|
96
|
+
});
|
|
97
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2 })).toMatchObject({
|
|
98
|
+
id: 2,
|
|
99
|
+
ipAddress: '2.2.2.2',
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
(0, vitest_1.it)('should ignore tcpoOnly options', async () => {
|
|
103
|
+
useDcOptions([
|
|
104
|
+
(0, test_1.createStub)('dcOption', { id: 1, ipAddress: '1.1.1.1', tcpoOnly: true }),
|
|
105
|
+
(0, test_1.createStub)('dcOption', { id: 1, ipAddress: '1.1.1.2' }),
|
|
106
|
+
]);
|
|
107
|
+
(0, vitest_1.expect)(await findOption({ dcId: 1 })).toMatchObject({
|
|
108
|
+
id: 1,
|
|
109
|
+
ipAddress: '1.1.1.2',
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
(0, vitest_1.it)('should respect allowMedia flag', async () => {
|
|
113
|
+
useDcOptions([
|
|
114
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '2.2.2.2', mediaOnly: true }),
|
|
115
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '2.2.2.3' }),
|
|
116
|
+
]);
|
|
117
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2 })).toMatchObject({
|
|
118
|
+
id: 2,
|
|
119
|
+
ipAddress: '2.2.2.3',
|
|
120
|
+
});
|
|
121
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2, allowMedia: true })).toMatchObject({
|
|
122
|
+
id: 2,
|
|
123
|
+
ipAddress: '2.2.2.2',
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
(0, vitest_1.it)('should respect preferMedia flag', async () => {
|
|
127
|
+
useDcOptions([
|
|
128
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '2.2.2.3' }),
|
|
129
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '2.2.2.2', mediaOnly: true }),
|
|
130
|
+
]);
|
|
131
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2 })).toMatchObject({
|
|
132
|
+
id: 2,
|
|
133
|
+
ipAddress: '2.2.2.3',
|
|
134
|
+
});
|
|
135
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2, allowMedia: true, preferMedia: true })).toMatchObject({
|
|
136
|
+
id: 2,
|
|
137
|
+
ipAddress: '2.2.2.2',
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
(0, vitest_1.it)('should respect allowIpv6 flag', async () => {
|
|
141
|
+
useDcOptions([
|
|
142
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '::1', ipv6: true }),
|
|
143
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '2.2.2.3' }),
|
|
144
|
+
]);
|
|
145
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2 })).toMatchObject({
|
|
146
|
+
id: 2,
|
|
147
|
+
ipAddress: '2.2.2.3',
|
|
148
|
+
});
|
|
149
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2, allowIpv6: true })).toMatchObject({
|
|
150
|
+
id: 2,
|
|
151
|
+
ipAddress: '::1',
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
(0, vitest_1.it)('should respect preferIpv6 flag', async () => {
|
|
155
|
+
useDcOptions([
|
|
156
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '2.2.2.3' }),
|
|
157
|
+
(0, test_1.createStub)('dcOption', { id: 2, ipAddress: '::1', ipv6: true }),
|
|
158
|
+
]);
|
|
159
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2 })).toMatchObject({
|
|
160
|
+
id: 2,
|
|
161
|
+
ipAddress: '2.2.2.3',
|
|
162
|
+
});
|
|
163
|
+
(0, vitest_1.expect)(await findOption({ dcId: 2, allowIpv6: true, preferIpv6: true })).toMatchObject({
|
|
164
|
+
id: 2,
|
|
165
|
+
ipAddress: '::1',
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=config-manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-manager.test.js","sourceRoot":"","sources":["../../../src/network/config-manager.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { createStub } from '@mtcute/test'\nimport { tl } from '@mtcute/tl'\n\nimport { ConfigManager } from './config-manager.js'\n\ndescribe('ConfigManager', () => {\n const config = createStub('config', {\n expires: 300,\n })\n const getConfig = vi.fn()\n\n beforeEach(() => {\n vi.useFakeTimers()\n vi.setSystemTime(0)\n getConfig.mockClear().mockImplementation(() => Promise.resolve(config))\n })\n afterEach(() => void vi.useRealTimers())\n\n it('should fetch initial config', async () => {\n const cm = new ConfigManager(getConfig)\n\n const fetchedConfig = await cm.get()\n\n expect(getConfig).toHaveBeenCalledTimes(1)\n expect(fetchedConfig).toEqual(config)\n expect(cm.getNow()).toEqual(config)\n })\n\n it('should automatically update config', async () => {\n const cm = new ConfigManager(getConfig)\n await cm.update()\n\n getConfig.mockImplementation(() =>\n Promise.resolve({\n ...config,\n expires: 600,\n }),\n )\n\n await vi.advanceTimersByTimeAsync(301_000)\n\n expect(getConfig).toHaveBeenCalledTimes(2)\n })\n\n it('should correctly determine stale config', () => {\n const cm = new ConfigManager(getConfig)\n expect(cm.isStale).toBe(true)\n\n cm.setConfig(config)\n expect(cm.isStale).toBe(false)\n\n vi.setSystemTime(300_000)\n expect(cm.isStale).toBe(true)\n })\n\n it('should not update config if not stale', async () => {\n const cm = new ConfigManager(getConfig)\n await cm.update()\n\n getConfig.mockClear()\n await cm.update()\n\n expect(getConfig).not.toHaveBeenCalled()\n })\n\n it('should not update config twice', async () => {\n const cm = new ConfigManager(getConfig)\n await cm.update()\n\n vi.setSystemTime(300_000)\n getConfig.mockClear()\n await Promise.all([cm.update(), cm.update()])\n\n expect(getConfig).toHaveBeenCalledOnce()\n })\n\n it('should call listeners on config update', async () => {\n const cm = new ConfigManager(getConfig)\n const listener = vi.fn()\n cm.onConfigUpdate(listener)\n await cm.update()\n\n vi.setSystemTime(300_000)\n cm.offConfigUpdate(listener)\n await cm.update()\n\n expect(listener).toHaveBeenCalledOnce()\n expect(listener).toHaveBeenCalledWith(config)\n })\n\n it('should correctly destroy', async () => {\n const cm = new ConfigManager(getConfig)\n await cm.update()\n\n cm.destroy()\n\n getConfig.mockClear()\n await vi.advanceTimersByTimeAsync(301_000)\n\n expect(getConfig).not.toHaveBeenCalled()\n })\n\n describe('findOption', () => {\n const useDcOptions = (options: tl.RawDcOption[]) => {\n getConfig.mockImplementation(() =>\n Promise.resolve({\n ...config,\n dcOptions: options,\n }),\n )\n }\n\n const findOption = async (params: Parameters<ConfigManager['findOption']>[0]) => {\n const cm = new ConfigManager(getConfig)\n await cm.update()\n\n return cm.findOption(params)\n }\n\n it('should find option by dc id', async () => {\n useDcOptions([\n createStub('dcOption', { id: 1, ipAddress: '1.1.1.1' }),\n createStub('dcOption', { id: 2, ipAddress: '2.2.2.2' }),\n ])\n\n expect(await findOption({ dcId: 1 })).toMatchObject({\n id: 1,\n ipAddress: '1.1.1.1',\n })\n expect(await findOption({ dcId: 2 })).toMatchObject({\n id: 2,\n ipAddress: '2.2.2.2',\n })\n })\n\n it('should ignore tcpoOnly options', async () => {\n useDcOptions([\n createStub('dcOption', { id: 1, ipAddress: '1.1.1.1', tcpoOnly: true }),\n createStub('dcOption', { id: 1, ipAddress: '1.1.1.2' }),\n ])\n\n expect(await findOption({ dcId: 1 })).toMatchObject({\n id: 1,\n ipAddress: '1.1.1.2',\n })\n })\n\n it('should respect allowMedia flag', async () => {\n useDcOptions([\n createStub('dcOption', { id: 2, ipAddress: '2.2.2.2', mediaOnly: true }),\n createStub('dcOption', { id: 2, ipAddress: '2.2.2.3' }),\n ])\n\n expect(await findOption({ dcId: 2 })).toMatchObject({\n id: 2,\n ipAddress: '2.2.2.3',\n })\n\n expect(await findOption({ dcId: 2, allowMedia: true })).toMatchObject({\n id: 2,\n ipAddress: '2.2.2.2',\n })\n })\n\n it('should respect preferMedia flag', async () => {\n useDcOptions([\n createStub('dcOption', { id: 2, ipAddress: '2.2.2.3' }),\n createStub('dcOption', { id: 2, ipAddress: '2.2.2.2', mediaOnly: true }),\n ])\n\n expect(await findOption({ dcId: 2 })).toMatchObject({\n id: 2,\n ipAddress: '2.2.2.3',\n })\n\n expect(await findOption({ dcId: 2, allowMedia: true, preferMedia: true })).toMatchObject({\n id: 2,\n ipAddress: '2.2.2.2',\n })\n })\n\n it('should respect allowIpv6 flag', async () => {\n useDcOptions([\n createStub('dcOption', { id: 2, ipAddress: '::1', ipv6: true }),\n createStub('dcOption', { id: 2, ipAddress: '2.2.2.3' }),\n ])\n\n expect(await findOption({ dcId: 2 })).toMatchObject({\n id: 2,\n ipAddress: '2.2.2.3',\n })\n\n expect(await findOption({ dcId: 2, allowIpv6: true })).toMatchObject({\n id: 2,\n ipAddress: '::1',\n })\n })\n\n it('should respect preferIpv6 flag', async () => {\n useDcOptions([\n createStub('dcOption', { id: 2, ipAddress: '2.2.2.3' }),\n createStub('dcOption', { id: 2, ipAddress: '::1', ipv6: true }),\n ])\n\n expect(await findOption({ dcId: 2 })).toMatchObject({\n id: 2,\n ipAddress: '2.2.2.3',\n })\n\n expect(await findOption({ dcId: 2, allowIpv6: true, preferIpv6: true })).toMatchObject({\n id: 2,\n ipAddress: '::1',\n })\n })\n })\n})\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const test_1 = require("@mtcute/test");
|
|
5
|
+
const index_js_1 = require("../utils/index.js");
|
|
6
|
+
const persistent_connection_js_1 = require("./persistent-connection.js");
|
|
7
|
+
const reconnection_js_1 = require("./reconnection.js");
|
|
8
|
+
class FakePersistentConnection extends persistent_connection_js_1.PersistentConnection {
|
|
9
|
+
constructor(params) {
|
|
10
|
+
const log = new index_js_1.LogManager();
|
|
11
|
+
log.level = 0;
|
|
12
|
+
super(params, log);
|
|
13
|
+
}
|
|
14
|
+
onConnected() {
|
|
15
|
+
this.onConnectionUsable();
|
|
16
|
+
}
|
|
17
|
+
onError() { }
|
|
18
|
+
onMessage() { }
|
|
19
|
+
}
|
|
20
|
+
(0, vitest_1.describe)('PersistentConnection', () => {
|
|
21
|
+
(0, vitest_1.beforeEach)(() => void vitest_1.vi.useFakeTimers());
|
|
22
|
+
(0, vitest_1.afterEach)(() => void vitest_1.vi.useRealTimers());
|
|
23
|
+
const create = async (params) => {
|
|
24
|
+
return new FakePersistentConnection({
|
|
25
|
+
crypto: await (0, test_1.defaultTestCryptoProvider)(),
|
|
26
|
+
transportFactory: () => new test_1.StubTelegramTransport({}),
|
|
27
|
+
dc: (0, test_1.createStub)('dcOption'),
|
|
28
|
+
testMode: false,
|
|
29
|
+
reconnectionStrategy: reconnection_js_1.defaultReconnectionStrategy,
|
|
30
|
+
...params,
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
(0, vitest_1.it)('should set up listeners on transport', async () => {
|
|
34
|
+
const transportFactory = vitest_1.vi.fn().mockImplementation(() => {
|
|
35
|
+
const transport = new test_1.StubTelegramTransport({});
|
|
36
|
+
vitest_1.vi.spyOn(transport, 'on');
|
|
37
|
+
return transport;
|
|
38
|
+
});
|
|
39
|
+
await create({ transportFactory });
|
|
40
|
+
const transport = transportFactory.mock.results[0].value;
|
|
41
|
+
(0, vitest_1.expect)(transport.on).toHaveBeenCalledWith('ready', vitest_1.expect.any(Function));
|
|
42
|
+
(0, vitest_1.expect)(transport.on).toHaveBeenCalledWith('message', vitest_1.expect.any(Function));
|
|
43
|
+
(0, vitest_1.expect)(transport.on).toHaveBeenCalledWith('error', vitest_1.expect.any(Function));
|
|
44
|
+
(0, vitest_1.expect)(transport.on).toHaveBeenCalledWith('close', vitest_1.expect.any(Function));
|
|
45
|
+
});
|
|
46
|
+
(0, vitest_1.it)('should properly reset old transport', async () => {
|
|
47
|
+
const transportFactory = vitest_1.vi.fn().mockImplementation(() => {
|
|
48
|
+
const transport = new test_1.StubTelegramTransport({});
|
|
49
|
+
vitest_1.vi.spyOn(transport, 'close');
|
|
50
|
+
return transport;
|
|
51
|
+
});
|
|
52
|
+
const pc = await create({ transportFactory });
|
|
53
|
+
const transport = transportFactory.mock.results[0].value;
|
|
54
|
+
pc.changeTransport(transportFactory);
|
|
55
|
+
(0, vitest_1.expect)(transport.close).toHaveBeenCalledOnce();
|
|
56
|
+
});
|
|
57
|
+
(0, vitest_1.it)('should buffer unsent packages', async () => {
|
|
58
|
+
const transportFactory = vitest_1.vi.fn().mockImplementation(() => {
|
|
59
|
+
const transport = new test_1.StubTelegramTransport({});
|
|
60
|
+
const transportConnect = transport.connect;
|
|
61
|
+
vitest_1.vi.spyOn(transport, 'connect').mockImplementation((dc, test) => {
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
transportConnect.call(transport, dc, test);
|
|
64
|
+
}, 100);
|
|
65
|
+
});
|
|
66
|
+
vitest_1.vi.spyOn(transport, 'send');
|
|
67
|
+
return transport;
|
|
68
|
+
});
|
|
69
|
+
const pc = await create({ transportFactory });
|
|
70
|
+
const transport = transportFactory.mock.results[0].value;
|
|
71
|
+
const data1 = new Uint8Array([1, 2, 3]);
|
|
72
|
+
const data2 = new Uint8Array([4, 5, 6]);
|
|
73
|
+
await pc.send(data1);
|
|
74
|
+
await pc.send(data2);
|
|
75
|
+
(0, vitest_1.expect)(transport.send).toHaveBeenCalledTimes(0);
|
|
76
|
+
await vitest_1.vi.advanceTimersByTimeAsync(150);
|
|
77
|
+
(0, vitest_1.expect)(transport.send).toHaveBeenCalledTimes(2);
|
|
78
|
+
(0, vitest_1.expect)(transport.send).toHaveBeenCalledWith(data1);
|
|
79
|
+
(0, vitest_1.expect)(transport.send).toHaveBeenCalledWith(data2);
|
|
80
|
+
});
|
|
81
|
+
(0, vitest_1.it)('should reconnect on close', async () => {
|
|
82
|
+
const reconnectionStrategy = vitest_1.vi.fn().mockImplementation(() => 1000);
|
|
83
|
+
const transportFactory = vitest_1.vi.fn().mockImplementation(() => new test_1.StubTelegramTransport({}));
|
|
84
|
+
const pc = await create({
|
|
85
|
+
reconnectionStrategy,
|
|
86
|
+
transportFactory,
|
|
87
|
+
});
|
|
88
|
+
const transport = transportFactory.mock.results[0].value;
|
|
89
|
+
pc.connect();
|
|
90
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(true));
|
|
91
|
+
transport.close();
|
|
92
|
+
(0, vitest_1.expect)(reconnectionStrategy).toHaveBeenCalledOnce();
|
|
93
|
+
(0, vitest_1.expect)(pc.isConnected).toBe(false);
|
|
94
|
+
await vitest_1.vi.advanceTimersByTimeAsync(1000);
|
|
95
|
+
(0, vitest_1.expect)(pc.isConnected).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
(0, vitest_1.describe)('inactivity timeout', () => {
|
|
98
|
+
(0, vitest_1.it)('should disconnect on inactivity (passed in constructor)', async () => {
|
|
99
|
+
const pc = await create({
|
|
100
|
+
inactivityTimeout: 1000,
|
|
101
|
+
});
|
|
102
|
+
pc.connect();
|
|
103
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(true));
|
|
104
|
+
vitest_1.vi.advanceTimersByTime(1000);
|
|
105
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(false));
|
|
106
|
+
});
|
|
107
|
+
(0, vitest_1.it)('should disconnect on inactivity (set up with setInactivityTimeout)', async () => {
|
|
108
|
+
const pc = await create();
|
|
109
|
+
pc.connect();
|
|
110
|
+
pc.setInactivityTimeout(1000);
|
|
111
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(true));
|
|
112
|
+
vitest_1.vi.advanceTimersByTime(1000);
|
|
113
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(false));
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.it)('should not disconnect on inactivity if disabled', async () => {
|
|
116
|
+
const pc = await create({
|
|
117
|
+
inactivityTimeout: 1000,
|
|
118
|
+
});
|
|
119
|
+
pc.connect();
|
|
120
|
+
pc.setInactivityTimeout(undefined);
|
|
121
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(true));
|
|
122
|
+
vitest_1.vi.advanceTimersByTime(1000);
|
|
123
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(true));
|
|
124
|
+
});
|
|
125
|
+
(0, vitest_1.it)('should reconnect after inactivity before sending', async () => {
|
|
126
|
+
const transportFactory = vitest_1.vi.fn().mockImplementation(() => {
|
|
127
|
+
const transport = new test_1.StubTelegramTransport({});
|
|
128
|
+
vitest_1.vi.spyOn(transport, 'connect');
|
|
129
|
+
vitest_1.vi.spyOn(transport, 'send');
|
|
130
|
+
return transport;
|
|
131
|
+
});
|
|
132
|
+
const pc = await create({
|
|
133
|
+
inactivityTimeout: 1000,
|
|
134
|
+
transportFactory,
|
|
135
|
+
});
|
|
136
|
+
const transport = transportFactory.mock.results[0].value;
|
|
137
|
+
pc.connect();
|
|
138
|
+
vitest_1.vi.advanceTimersByTime(1000);
|
|
139
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(false));
|
|
140
|
+
vitest_1.vi.mocked(transport.connect).mockClear();
|
|
141
|
+
await pc.send(new Uint8Array([1, 2, 3]));
|
|
142
|
+
(0, vitest_1.expect)(transport.connect).toHaveBeenCalledOnce();
|
|
143
|
+
(0, vitest_1.expect)(transport.send).toHaveBeenCalledOnce();
|
|
144
|
+
});
|
|
145
|
+
(0, vitest_1.it)('should propagate errors', async () => {
|
|
146
|
+
const transportFactory = vitest_1.vi.fn().mockImplementation(() => new test_1.StubTelegramTransport({}));
|
|
147
|
+
const pc = await create({ transportFactory });
|
|
148
|
+
const transport = transportFactory.mock.results[0].value;
|
|
149
|
+
pc.connect();
|
|
150
|
+
await vitest_1.vi.waitFor(() => (0, vitest_1.expect)(pc.isConnected).toBe(true));
|
|
151
|
+
const onErrorSpy = vitest_1.vi.spyOn(pc, 'onError');
|
|
152
|
+
transport.emit('error', new Error('test error'));
|
|
153
|
+
(0, vitest_1.expect)(onErrorSpy).toHaveBeenCalledOnce();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=persistent-connection.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-connection.test.js","sourceRoot":"","sources":["../../../src/network/persistent-connection.test.ts"],"names":[],"mappings":";;AAAA,mCAAwE;AAExE,uCAA2F;AAE3F,gDAA8C;AAC9C,yEAA6F;AAC7F,uDAA+D;AAE/D,MAAM,wBAAyB,SAAQ,+CAAoB;IACvD,YAAY,MAAkC;QAC1C,MAAM,GAAG,GAAG,IAAI,qBAAU,EAAE,CAAA;QAC5B,GAAG,CAAC,KAAK,GAAG,CAAC,CAAA;QACb,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACtB,CAAC;IAED,WAAW;QACP,IAAI,CAAC,kBAAkB,EAAE,CAAA;IAC7B,CAAC;IACD,OAAO,KAAI,CAAC;IACZ,SAAS,KAAI,CAAC;CACjB;AAED,IAAA,iBAAQ,EAAC,sBAAsB,EAAE,GAAG,EAAE;IAClC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,KAAK,WAAE,CAAC,aAAa,EAAE,CAAC,CAAA;IACzC,IAAA,kBAAS,EAAC,GAAG,EAAE,CAAC,KAAK,WAAE,CAAC,aAAa,EAAE,CAAC,CAAA;IAExC,MAAM,MAAM,GAAG,KAAK,EAAE,MAA4C,EAAE,EAAE;QAClE,OAAO,IAAI,wBAAwB,CAAC;YAChC,MAAM,EAAE,MAAM,IAAA,gCAAyB,GAAE;YACzC,gBAAgB,EAAE,GAAG,EAAE,CAAC,IAAI,4BAAqB,CAAC,EAAE,CAAC;YACrD,EAAE,EAAE,IAAA,iBAAU,EAAC,UAAU,CAAC;YAC1B,QAAQ,EAAE,KAAK;YACf,oBAAoB,EAAE,6CAA2B;YACjD,GAAG,MAAM;SACZ,CAAC,CAAA;IACN,CAAC,CAAA;IAED,IAAA,WAAE,EAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,gBAAgB,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACrD,MAAM,SAAS,GAAG,IAAI,4BAAqB,CAAC,EAAE,CAAC,CAAA;YAE/C,WAAE,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YAEzB,OAAO,SAAS,CAAA;QACpB,CAAC,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAA;QAElC,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAA8B,CAAA;QAEjF,IAAA,eAAM,EAAC,SAAS,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,eAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QACxE,IAAA,eAAM,EAAC,SAAS,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,SAAS,EAAE,eAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC1E,IAAA,eAAM,EAAC,SAAS,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,eAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QACxE,IAAA,eAAM,EAAC,SAAS,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,eAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,gBAAgB,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACrD,MAAM,SAAS,GAAG,IAAI,4BAAqB,CAAC,EAAE,CAAC,CAAA;YAE/C,WAAE,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;YAE5B,OAAO,SAAS,CAAA;QACpB,CAAC,CAAC,CAAA;QACF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAA;QAE7C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAA8B,CAAA;QAEjF,EAAE,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAA;QAEpC,IAAA,eAAM,EAAC,SAAS,CAAC,KAAK,CAAC,CAAC,oBAAoB,EAAE,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,gBAAgB,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACrD,MAAM,SAAS,GAAG,IAAI,4BAAqB,CAAC,EAAE,CAAC,CAAA;YAE/C,MAAM,gBAAgB,GAAG,SAAS,CAAC,OAAO,CAAA;YAC1C,WAAE,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE;gBAC3D,UAAU,CAAC,GAAG,EAAE;oBACZ,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;gBAC9C,CAAC,EAAE,GAAG,CAAC,CAAA;YACX,CAAC,CAAC,CAAA;YACF,WAAE,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;YAE3B,OAAO,SAAS,CAAA;QACpB,CAAC,CAAC,CAAA;QACF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAA;QAE7C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAA8B,CAAA;QAEjF,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAEvC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAEpB,IAAA,eAAM,EAAC,SAAS,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;QAE/C,MAAM,WAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAA;QAEtC,IAAA,eAAM,EAAC,SAAS,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;QAC/C,IAAA,eAAM,EAAC,SAAS,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAA;QAClD,IAAA,eAAM,EAAC,SAAS,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,oBAAoB,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QACnE,MAAM,gBAAgB,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,4BAAqB,CAAC,EAAE,CAAC,CAAC,CAAA;QAExF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC;YACpB,oBAAoB;YACpB,gBAAgB;SACnB,CAAC,CAAA;QAEF,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAA8B,CAAA;QAEjF,EAAE,CAAC,OAAO,EAAE,CAAA;QAEZ,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAEzD,SAAS,CAAC,KAAK,EAAE,CAAA;QAEjB,IAAA,eAAM,EAAC,oBAAoB,CAAC,CAAC,oBAAoB,EAAE,CAAA;QACnD,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAElC,MAAM,WAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAA;QAEvC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,IAAA,iBAAQ,EAAC,oBAAoB,EAAE,GAAG,EAAE;QAChC,IAAA,WAAE,EAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC;gBACpB,iBAAiB,EAAE,IAAI;aAC1B,CAAC,CAAA;YAEF,EAAE,CAAC,OAAO,EAAE,CAAA;YAEZ,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAEzD,WAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;YAE5B,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAC9D,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;YAChF,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAA;YAEzB,EAAE,CAAC,OAAO,EAAE,CAAA;YACZ,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAA;YAE7B,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAEzD,WAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;YAE5B,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAC9D,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC;gBACpB,iBAAiB,EAAE,IAAI;aAC1B,CAAC,CAAA;YAEF,EAAE,CAAC,OAAO,EAAE,CAAA;YACZ,EAAE,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;YAElC,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAEzD,WAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;YAE5B,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC7D,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,gBAAgB,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE;gBACrD,MAAM,SAAS,GAAG,IAAI,4BAAqB,CAAC,EAAE,CAAC,CAAA;gBAE/C,WAAE,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;gBAC9B,WAAE,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;gBAE3B,OAAO,SAAS,CAAA;YACpB,CAAC,CAAC,CAAA;YAEF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC;gBACpB,iBAAiB,EAAE,IAAI;gBACvB,gBAAgB;aACnB,CAAC,CAAA;YACF,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAA8B,CAAA;YAEjF,EAAE,CAAC,OAAO,EAAE,CAAA;YAEZ,WAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;YAE5B,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;YAE1D,WAAE,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAA;YAExC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;YAExC,IAAA,eAAM,EAAC,SAAS,CAAC,OAAO,CAAC,CAAC,oBAAoB,EAAE,CAAA;YAChD,IAAA,eAAM,EAAC,SAAS,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAA;QACjD,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACrC,MAAM,gBAAgB,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,4BAAqB,CAAC,EAAE,CAAC,CAAC,CAAA;YAExF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAA;YAC7C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAA8B,CAAA;YAEjF,EAAE,CAAC,OAAO,EAAE,CAAA;YAEZ,MAAM,WAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAEzD,MAAM,UAAU,GAAG,WAAE,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,CAAA;YAE1C,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAA;YAEhD,IAAA,eAAM,EAAC,UAAU,CAAC,CAAC,oBAAoB,EAAE,CAAA;QAC7C,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { createStub, defaultTestCryptoProvider, StubTelegramTransport } from '@mtcute/test'\n\nimport { LogManager } from '../utils/index.js'\nimport { PersistentConnection, PersistentConnectionParams } from './persistent-connection.js'\nimport { defaultReconnectionStrategy } from './reconnection.js'\n\nclass FakePersistentConnection extends PersistentConnection {\n constructor(params: PersistentConnectionParams) {\n const log = new LogManager()\n log.level = 0\n super(params, log)\n }\n\n onConnected() {\n this.onConnectionUsable()\n }\n onError() {}\n onMessage() {}\n}\n\ndescribe('PersistentConnection', () => {\n beforeEach(() => void vi.useFakeTimers())\n afterEach(() => void vi.useRealTimers())\n\n const create = async (params?: Partial<PersistentConnectionParams>) => {\n return new FakePersistentConnection({\n crypto: await defaultTestCryptoProvider(),\n transportFactory: () => new StubTelegramTransport({}),\n dc: createStub('dcOption'),\n testMode: false,\n reconnectionStrategy: defaultReconnectionStrategy,\n ...params,\n })\n }\n\n it('should set up listeners on transport', async () => {\n const transportFactory = vi.fn().mockImplementation(() => {\n const transport = new StubTelegramTransport({})\n\n vi.spyOn(transport, 'on')\n\n return transport\n })\n await create({ transportFactory })\n\n const transport = transportFactory.mock.results[0].value as StubTelegramTransport\n\n expect(transport.on).toHaveBeenCalledWith('ready', expect.any(Function))\n expect(transport.on).toHaveBeenCalledWith('message', expect.any(Function))\n expect(transport.on).toHaveBeenCalledWith('error', expect.any(Function))\n expect(transport.on).toHaveBeenCalledWith('close', expect.any(Function))\n })\n\n it('should properly reset old transport', async () => {\n const transportFactory = vi.fn().mockImplementation(() => {\n const transport = new StubTelegramTransport({})\n\n vi.spyOn(transport, 'close')\n\n return transport\n })\n const pc = await create({ transportFactory })\n\n const transport = transportFactory.mock.results[0].value as StubTelegramTransport\n\n pc.changeTransport(transportFactory)\n\n expect(transport.close).toHaveBeenCalledOnce()\n })\n\n it('should buffer unsent packages', async () => {\n const transportFactory = vi.fn().mockImplementation(() => {\n const transport = new StubTelegramTransport({})\n\n const transportConnect = transport.connect\n vi.spyOn(transport, 'connect').mockImplementation((dc, test) => {\n setTimeout(() => {\n transportConnect.call(transport, dc, test)\n }, 100)\n })\n vi.spyOn(transport, 'send')\n\n return transport\n })\n const pc = await create({ transportFactory })\n\n const transport = transportFactory.mock.results[0].value as StubTelegramTransport\n\n const data1 = new Uint8Array([1, 2, 3])\n const data2 = new Uint8Array([4, 5, 6])\n\n await pc.send(data1)\n await pc.send(data2)\n\n expect(transport.send).toHaveBeenCalledTimes(0)\n\n await vi.advanceTimersByTimeAsync(150)\n\n expect(transport.send).toHaveBeenCalledTimes(2)\n expect(transport.send).toHaveBeenCalledWith(data1)\n expect(transport.send).toHaveBeenCalledWith(data2)\n })\n\n it('should reconnect on close', async () => {\n const reconnectionStrategy = vi.fn().mockImplementation(() => 1000)\n const transportFactory = vi.fn().mockImplementation(() => new StubTelegramTransport({}))\n\n const pc = await create({\n reconnectionStrategy,\n transportFactory,\n })\n\n const transport = transportFactory.mock.results[0].value as StubTelegramTransport\n\n pc.connect()\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(true))\n\n transport.close()\n\n expect(reconnectionStrategy).toHaveBeenCalledOnce()\n expect(pc.isConnected).toBe(false)\n\n await vi.advanceTimersByTimeAsync(1000)\n\n expect(pc.isConnected).toBe(true)\n })\n\n describe('inactivity timeout', () => {\n it('should disconnect on inactivity (passed in constructor)', async () => {\n const pc = await create({\n inactivityTimeout: 1000,\n })\n\n pc.connect()\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(true))\n\n vi.advanceTimersByTime(1000)\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(false))\n })\n\n it('should disconnect on inactivity (set up with setInactivityTimeout)', async () => {\n const pc = await create()\n\n pc.connect()\n pc.setInactivityTimeout(1000)\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(true))\n\n vi.advanceTimersByTime(1000)\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(false))\n })\n\n it('should not disconnect on inactivity if disabled', async () => {\n const pc = await create({\n inactivityTimeout: 1000,\n })\n\n pc.connect()\n pc.setInactivityTimeout(undefined)\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(true))\n\n vi.advanceTimersByTime(1000)\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(true))\n })\n\n it('should reconnect after inactivity before sending', async () => {\n const transportFactory = vi.fn().mockImplementation(() => {\n const transport = new StubTelegramTransport({})\n\n vi.spyOn(transport, 'connect')\n vi.spyOn(transport, 'send')\n\n return transport\n })\n\n const pc = await create({\n inactivityTimeout: 1000,\n transportFactory,\n })\n const transport = transportFactory.mock.results[0].value as StubTelegramTransport\n\n pc.connect()\n\n vi.advanceTimersByTime(1000)\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(false))\n\n vi.mocked(transport.connect).mockClear()\n\n await pc.send(new Uint8Array([1, 2, 3]))\n\n expect(transport.connect).toHaveBeenCalledOnce()\n expect(transport.send).toHaveBeenCalledOnce()\n })\n\n it('should propagate errors', async () => {\n const transportFactory = vi.fn().mockImplementation(() => new StubTelegramTransport({}))\n\n const pc = await create({ transportFactory })\n const transport = transportFactory.mock.results[0].value as StubTelegramTransport\n\n pc.connect()\n\n await vi.waitFor(() => expect(pc.isConnected).toBe(true))\n\n const onErrorSpy = vi.spyOn(pc, 'onError')\n\n transport.emit('error', new Error('test error'))\n\n expect(onErrorSpy).toHaveBeenCalledOnce()\n })\n })\n})\n"]}
|
|
@@ -1359,7 +1359,6 @@ class SessionConnection extends persistent_connection_js_1.PersistentConnection
|
|
|
1359
1359
|
});
|
|
1360
1360
|
}
|
|
1361
1361
|
const result = writer.result();
|
|
1362
|
-
// probably the easiest way lol
|
|
1363
1362
|
this.log.debug('sending %d messages: size = %db, acks = %d (msg_id = %s), ping = %s (msg_id = %s), state_req = %s (msg_id = %s), resend = %s (msg_id = %s), cancels = %s (msg_id = %s), rpc = %s, container = %s, root msg_id = %l', messageCount, packetSize, ackMsgIds?.length || 'false', ackMsgIds?.map((it) => it.toString()), Boolean(pingRequest), pingMsgId, getStateMsgIds?.map((it) => it.toString()) || 'false', getStateMsgId, resendMsgIds?.map((it) => it.toString()) || 'false', cancelRpcs, cancelRpcs?.map((it) => it.toString()) || 'false', resendMsgId, rpcToSend.map((it) => it.method), useContainer, rootMsgId);
|
|
1364
1363
|
const enc = this._session.encryptMessage(result);
|
|
1365
1364
|
this.send(enc).catch((err) => {
|
|
@@ -1368,7 +1367,9 @@ class SessionConnection extends persistent_connection_js_1.PersistentConnection
|
|
|
1368
1367
|
if (ackMsgIds) {
|
|
1369
1368
|
this._session.queuedAcks.splice(0, 0, ...ackMsgIds);
|
|
1370
1369
|
}
|
|
1371
|
-
|
|
1370
|
+
if (rootMsgId) {
|
|
1371
|
+
this._onMessageFailed(rootMsgId, 'unknown error');
|
|
1372
|
+
}
|
|
1372
1373
|
});
|
|
1373
1374
|
}
|
|
1374
1375
|
}
|