@mtkruto/node 0.171.0 → 0.180.1
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/esm/0_deps.d.ts +1 -0
- package/esm/0_deps.d.ts.map +1 -1
- package/esm/0_deps.js +1 -0
- package/esm/client/0_params.d.ts +54 -8
- package/esm/client/0_params.d.ts.map +1 -1
- package/esm/client/1_client_generic.d.ts +72 -1
- package/esm/client/1_client_generic.d.ts.map +1 -1
- package/esm/client/2_file_manager.d.ts +9 -1
- package/esm/client/2_file_manager.d.ts.map +1 -1
- package/esm/client/2_file_manager.js +93 -37
- package/esm/client/3_secret_chat_manager.d.ts +11 -2
- package/esm/client/3_secret_chat_manager.d.ts.map +1 -1
- package/esm/client/3_secret_chat_manager.js +322 -11
- package/esm/client/4_context.d.ts +24 -6
- package/esm/client/4_context.d.ts.map +1 -1
- package/esm/client/4_context.js +53 -0
- package/esm/client/6_client.d.ts +72 -1
- package/esm/client/6_client.d.ts.map +1 -1
- package/esm/client/6_client.js +89 -0
- package/esm/client/6_client_dispatcher.d.ts +72 -1
- package/esm/client/6_client_dispatcher.d.ts.map +1 -1
- package/esm/client/6_client_dispatcher.js +89 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts +9 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.js +2 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts +2 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts +69 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.js +237 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.js +2277 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts +13 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.js +46 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts +76 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.js +132 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts +149 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.js +270 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts +22 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.js +23 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +40 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +61 -0
- package/esm/tl/0_utilities.d.ts.map +1 -1
- package/esm/tl/0_utilities.js +44 -2
- package/esm/tl/1_tl_writer.d.ts.map +1 -1
- package/esm/tl/1_tl_writer.js +6 -1
- package/esm/types/1_sticker.d.ts +7 -9
- package/esm/types/1_sticker.d.ts.map +1 -1
- package/esm/types/1_sticker.js +1 -6
- package/package.json +1 -1
- package/script/0_deps.d.ts +1 -0
- package/script/0_deps.d.ts.map +1 -1
- package/script/0_deps.js +7 -5
- package/script/client/0_params.d.ts +54 -8
- package/script/client/0_params.d.ts.map +1 -1
- package/script/client/1_client_generic.d.ts +72 -1
- package/script/client/1_client_generic.d.ts.map +1 -1
- package/script/client/2_file_manager.d.ts +9 -1
- package/script/client/2_file_manager.d.ts.map +1 -1
- package/script/client/2_file_manager.js +90 -34
- package/script/client/3_secret_chat_manager.d.ts +11 -2
- package/script/client/3_secret_chat_manager.d.ts.map +1 -1
- package/script/client/3_secret_chat_manager.js +319 -8
- package/script/client/4_context.d.ts +24 -6
- package/script/client/4_context.d.ts.map +1 -1
- package/script/client/4_context.js +53 -0
- package/script/client/6_client.d.ts +72 -1
- package/script/client/6_client.d.ts.map +1 -1
- package/script/client/6_client.js +89 -0
- package/script/client/6_client_dispatcher.d.ts +72 -1
- package/script/client/6_client_dispatcher.d.ts.map +1 -1
- package/script/client/6_client_dispatcher.js +89 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts +9 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_types.js +3 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts +2 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts +69 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.js +255 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.js +2315 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts +13 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.js +51 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts +76 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.js +169 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts +149 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/crypto.js +306 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts +22 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/mod.js +39 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +40 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +64 -0
- package/script/tl/0_utilities.d.ts.map +1 -1
- package/script/tl/0_utilities.js +43 -1
- package/script/tl/1_tl_writer.d.ts.map +1 -1
- package/script/tl/1_tl_writer.js +6 -1
- package/script/types/1_sticker.d.ts +7 -9
- package/script/types/1_sticker.d.ts.map +1 -1
- package/script/types/1_sticker.js +1 -6
|
@@ -84,7 +84,7 @@ class FileManager {
|
|
|
84
84
|
this.#progressIds.add(id);
|
|
85
85
|
return Promise.resolve(String(id));
|
|
86
86
|
}
|
|
87
|
-
async upload(file, params, checkName, allowStream = true) {
|
|
87
|
+
async upload(file, params, checkName, allowStream = true, encryptionInformation) {
|
|
88
88
|
if (params?.progressId !== undefined && !this.#progressIds.has(BigInt(params.progressId))) {
|
|
89
89
|
throw new _0_errors_js_1.InputError("Invalid progressId.");
|
|
90
90
|
}
|
|
@@ -108,15 +108,28 @@ class FileManager {
|
|
|
108
108
|
this.#Lupload.debug("uploading " + whatIsUploaded + " with chunk size of " + chunkSize + " and pool size of " + poolSize + " and file ID of " + fileId);
|
|
109
109
|
let result;
|
|
110
110
|
if (contents instanceof Uint8Array) {
|
|
111
|
-
result = await this.#uploadBuffer(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal);
|
|
111
|
+
result = await this.#uploadBuffer(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal, encryptionInformation);
|
|
112
112
|
}
|
|
113
113
|
else {
|
|
114
|
-
result = await this.#uploadStream(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal);
|
|
114
|
+
result = await this.#uploadStream(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal, encryptionInformation);
|
|
115
115
|
}
|
|
116
116
|
this.#Lupload.debug(`[${fileId}] uploaded ` + result.parts + " part(s)");
|
|
117
117
|
if (checkName) {
|
|
118
118
|
name = checkName(name, result.firstPart);
|
|
119
119
|
}
|
|
120
|
+
if (encryptionInformation) {
|
|
121
|
+
const digest = new Uint8Array(await _0_deps_js_1.crypto.subtle.digest("MD5", (0, _0_deps_js_1.concat)([encryptionInformation.key, encryptionInformation.iv])));
|
|
122
|
+
const right = digest.subarray(4, 8);
|
|
123
|
+
const key_fingerprint = Number((0, _1_utilities_js_1.intFromBytes)(digest.subarray(0, 4).map((v, i) => v ^ right[i])));
|
|
124
|
+
if (result.isSmall) {
|
|
125
|
+
const inputEncryptedFile = { _: "inputEncryptedFileUploaded", id: fileId, parts: result.parts, key_fingerprint, md5_checksum: "" };
|
|
126
|
+
return { inputEncryptedFile, fileSize: result.fileSize };
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const inputEncryptedFile = { _: "inputEncryptedFileBigUploaded", id: fileId, parts: result.parts, key_fingerprint };
|
|
130
|
+
return { inputEncryptedFile, fileSize: result.fileSize };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
120
133
|
if (result.isSmall) {
|
|
121
134
|
return { _: "inputFile", id: fileId, name, parts: result.parts, md5_checksum: "" };
|
|
122
135
|
}
|
|
@@ -124,12 +137,14 @@ class FileManager {
|
|
|
124
137
|
return { _: "inputFileBig", id: fileId, name, parts: result.parts };
|
|
125
138
|
}
|
|
126
139
|
}
|
|
127
|
-
async #uploadStream(stream, fileId, mustTrackProgress, chunkSize, poolSize, signal) {
|
|
140
|
+
async #uploadStream(stream, fileId, mustTrackProgress, chunkSize, poolSize, signal, encryptionInformation) {
|
|
128
141
|
let part;
|
|
129
142
|
let promises = new Array();
|
|
130
143
|
let ms = 0.05;
|
|
131
144
|
let uploaded = 0;
|
|
132
145
|
let firstPart;
|
|
146
|
+
let iv = encryptionInformation?.iv;
|
|
147
|
+
let fileSize = 0;
|
|
133
148
|
for await (part of (0, _1_utilities_js_1.iterateReadableStream)(stream.pipeThrough(new _1_utilities_js_1.PartStream(chunkSize)))) {
|
|
134
149
|
if (!part.isSmall && part.part > 0) {
|
|
135
150
|
await (0, _0_deps_js_1.delay)(ms);
|
|
@@ -138,6 +153,16 @@ class FileManager {
|
|
|
138
153
|
if (!firstPart) {
|
|
139
154
|
firstPart = part.bytes;
|
|
140
155
|
}
|
|
156
|
+
if (encryptionInformation) {
|
|
157
|
+
fileSize += part.bytes.byteLength;
|
|
158
|
+
if (part.bytes.byteLength % 16 !== 0) {
|
|
159
|
+
part.bytes = (0, _0_deps_js_1.concat)([part.bytes, _0_deps_js_1.crypto.getRandomValues(new Uint8Array((16 - part.bytes.length % 16) % 16))]);
|
|
160
|
+
}
|
|
161
|
+
const right = part.bytes.subarray(-16);
|
|
162
|
+
part.bytes = (0, _0_deps_js_1.ige256Encrypt)(part.bytes, encryptionInformation.key, iv);
|
|
163
|
+
const left = part.bytes.subarray(-16);
|
|
164
|
+
iv = (0, _0_deps_js_1.concat)([left, right]);
|
|
165
|
+
}
|
|
141
166
|
promises.push(this.#uploadPart(fileId, part.totalParts, !part.isSmall, part.part, part.bytes, signal).then(() => {
|
|
142
167
|
if (mustTrackProgress) {
|
|
143
168
|
uploaded += part.bytes.byteLength;
|
|
@@ -167,9 +192,9 @@ class FileManager {
|
|
|
167
192
|
isUploaded: true,
|
|
168
193
|
},
|
|
169
194
|
});
|
|
170
|
-
return { isSmall: part.isSmall, parts: part.totalParts, firstPart };
|
|
195
|
+
return { isSmall: part.isSmall, parts: part.totalParts, firstPart, fileSize };
|
|
171
196
|
}
|
|
172
|
-
async #uploadBuffer(buffer, fileId, mustTrackProgress, chunkSize, poolSize, signal) {
|
|
197
|
+
async #uploadBuffer(buffer, fileId, mustTrackProgress, chunkSize, poolSize, signal, encryptionInformation) {
|
|
173
198
|
const isBig = buffer.byteLength > _a.#BIG_FILE_THRESHOLD;
|
|
174
199
|
const partCount = Math.ceil(buffer.byteLength / chunkSize);
|
|
175
200
|
let promises = new Array();
|
|
@@ -177,15 +202,30 @@ class FileManager {
|
|
|
177
202
|
let ms = 0.05;
|
|
178
203
|
let uploaded = 0;
|
|
179
204
|
let firstPart;
|
|
205
|
+
let iv = encryptionInformation?.iv;
|
|
206
|
+
let fileSize = 0;
|
|
180
207
|
main: for (let part = 0; part < partCount;) {
|
|
181
208
|
for (let i = 0; i < poolSize; ++i) {
|
|
182
209
|
for (let i = 0; i < _0_utilities_js_1.UPLOAD_REQUEST_PER_CONNECTION; ++i) {
|
|
183
210
|
const start = part * chunkSize;
|
|
184
211
|
const end = start + chunkSize;
|
|
185
|
-
|
|
212
|
+
let bytes = buffer.subarray(start, end);
|
|
186
213
|
if (!bytes.byteLength) {
|
|
187
214
|
break main;
|
|
188
215
|
}
|
|
216
|
+
if (!firstPart) {
|
|
217
|
+
firstPart = bytes;
|
|
218
|
+
}
|
|
219
|
+
if (encryptionInformation) {
|
|
220
|
+
fileSize += bytes.byteLength;
|
|
221
|
+
if (bytes.byteLength % 16 !== 0) {
|
|
222
|
+
bytes = (0, _0_deps_js_1.concat)([bytes, _0_deps_js_1.crypto.getRandomValues(new Uint8Array((16 - bytes.length % 16) % 16))]);
|
|
223
|
+
}
|
|
224
|
+
const right = bytes.subarray(-16);
|
|
225
|
+
bytes = (0, _0_deps_js_1.ige256Encrypt)(bytes, encryptionInformation.key, iv);
|
|
226
|
+
const left = bytes.subarray(-16);
|
|
227
|
+
iv = (0, _0_deps_js_1.concat)([left, right]);
|
|
228
|
+
}
|
|
189
229
|
if (!started) {
|
|
190
230
|
started = true;
|
|
191
231
|
}
|
|
@@ -193,9 +233,6 @@ class FileManager {
|
|
|
193
233
|
await (0, _0_deps_js_1.delay)(ms);
|
|
194
234
|
ms = Math.max(ms * .8, 0.003);
|
|
195
235
|
}
|
|
196
|
-
if (!firstPart) {
|
|
197
|
-
firstPart = bytes;
|
|
198
|
-
}
|
|
199
236
|
promises.push(this.#uploadPart(fileId, partCount, isBig, part++, bytes, signal).then(() => {
|
|
200
237
|
if (mustTrackProgress) {
|
|
201
238
|
uploaded += bytes.byteLength;
|
|
@@ -229,7 +266,7 @@ class FileManager {
|
|
|
229
266
|
isUploaded: true,
|
|
230
267
|
},
|
|
231
268
|
});
|
|
232
|
-
return { isSmall: !isBig, parts: partCount, firstPart };
|
|
269
|
+
return { isSmall: !isBig, parts: partCount, firstPart, fileSize };
|
|
233
270
|
}
|
|
234
271
|
async #uploadPart(fileId, partCount, isBig, index, bytes, signal) {
|
|
235
272
|
let retryIn = 1;
|
|
@@ -399,27 +436,29 @@ class FileManager {
|
|
|
399
436
|
let offset = params?.offset ? BigInt(params.offset) : 0n;
|
|
400
437
|
let part = 0;
|
|
401
438
|
let totalSize = 0;
|
|
402
|
-
|
|
439
|
+
const requestCount = _0_utilities_js_1.DOWNLOAD_POOL_SIZE * _0_utilities_js_1.DOWNLOAD_REQUEST_PER_CONNECTION;
|
|
440
|
+
let finished = false;
|
|
403
441
|
while (true) {
|
|
404
442
|
signal?.throwIfAborted();
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
try {
|
|
408
|
-
const file = await this.#c.invoke({ _: "upload.getFile", location, offset, limit }, { dc, type: "download" });
|
|
443
|
+
const results = await Promise.all(Array.from({ length: requestCount }, (_, i) => this.#downloadPart(location, offset + BigInt(i * limit), limit, dc, signal, id, part + i)));
|
|
444
|
+
for (const result of results) {
|
|
409
445
|
signal?.throwIfAborted();
|
|
410
|
-
if (_2_tl_js_1.Api.is("upload.file",
|
|
411
|
-
const downloadedSize =
|
|
412
|
-
|
|
446
|
+
if (_2_tl_js_1.Api.is("upload.file", result)) {
|
|
447
|
+
const downloadedSize = result.bytes.byteLength;
|
|
448
|
+
finished = downloadedSize < limit;
|
|
413
449
|
if (decryptionInformation) {
|
|
414
|
-
const
|
|
450
|
+
const left = result.bytes.subarray(-16);
|
|
451
|
+
const decryptedBytes = (0, _0_deps_js_1.ige256Decrypt)(result.bytes, decryptionInformation.key, decryptionInformation.iv);
|
|
452
|
+
const right = decryptedBytes.subarray(-16);
|
|
415
453
|
const remainingSize = Math.max(0, fileSize - totalSize);
|
|
416
|
-
|
|
417
|
-
totalSize +=
|
|
454
|
+
result.bytes = decryptedBytes.slice(0, remainingSize);
|
|
455
|
+
totalSize += result.bytes.byteLength;
|
|
418
456
|
finished = totalSize >= fileSize;
|
|
457
|
+
decryptionInformation.iv = (0, _0_deps_js_1.concat)([left, right]);
|
|
419
458
|
}
|
|
420
|
-
yield
|
|
459
|
+
yield result.bytes;
|
|
421
460
|
if (id !== null) {
|
|
422
|
-
await this.#c.storage.saveFilePart(id, part,
|
|
461
|
+
await this.#c.storage.saveFilePart(id, part, result.bytes);
|
|
423
462
|
signal?.throwIfAborted();
|
|
424
463
|
}
|
|
425
464
|
++part;
|
|
@@ -437,8 +476,19 @@ class FileManager {
|
|
|
437
476
|
else {
|
|
438
477
|
(0, _0_deps_js_1.unreachable)();
|
|
439
478
|
}
|
|
440
|
-
|
|
441
|
-
|
|
479
|
+
}
|
|
480
|
+
if (finished) {
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
async #downloadPart(location, offset, limit, dc, signal, id, part) {
|
|
486
|
+
let retryIn = 1;
|
|
487
|
+
let errorCount = 0;
|
|
488
|
+
while (true) {
|
|
489
|
+
try {
|
|
490
|
+
signal?.throwIfAborted();
|
|
491
|
+
return await this.#c.invoke({ _: "upload.getFile", location, offset, limit }, { dc, type: "download" });
|
|
442
492
|
}
|
|
443
493
|
catch (err) {
|
|
444
494
|
if (typeof err === "object" && err instanceof _0_deps_js_1.AssertionError) {
|
|
@@ -447,7 +497,7 @@ class FileManager {
|
|
|
447
497
|
++errorCount;
|
|
448
498
|
if (errorCount > 20) {
|
|
449
499
|
retryIn = 0;
|
|
450
|
-
errorCount =
|
|
500
|
+
errorCount = 20;
|
|
451
501
|
}
|
|
452
502
|
await this.#handleError(err, retryIn, `[${id}-${part + 1}]`);
|
|
453
503
|
signal?.throwIfAborted();
|
|
@@ -536,13 +586,19 @@ class FileManager {
|
|
|
536
586
|
}
|
|
537
587
|
}
|
|
538
588
|
else if (fileId_.location.type === "common") {
|
|
539
|
-
const location =
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
589
|
+
const location = fileId_.type === _3_types_js_1.FileType.Encrypted
|
|
590
|
+
? {
|
|
591
|
+
_: "inputEncryptedFileLocation",
|
|
592
|
+
id: fileId_.location.id,
|
|
593
|
+
access_hash: fileId_.location.accessHash,
|
|
594
|
+
}
|
|
595
|
+
: {
|
|
596
|
+
_: "inputDocumentFileLocation",
|
|
597
|
+
id: fileId_.location.id,
|
|
598
|
+
access_hash: fileId_.location.accessHash,
|
|
599
|
+
file_reference: fileId_.fileReference ?? new Uint8Array(),
|
|
600
|
+
thumb_size: "",
|
|
601
|
+
};
|
|
546
602
|
yield* this.downloadInner(location, fileId_.dcId, params);
|
|
547
603
|
}
|
|
548
604
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Api } from "../2_tl.js";
|
|
2
|
-
import { type ID, type Update } from "../3_types.js";
|
|
3
|
-
import type { SendSecretContactParams, SendSecretLocationParams, SendSecretMessageParams, SendSecretVenueParams } from "./0_params.js";
|
|
2
|
+
import { type FileSource, type ID, type Sticker, type Update } from "../3_types.js";
|
|
3
|
+
import type { EndSecretChatParams, SendSecretAnimationParams, SendSecretAudioParams, SendSecretContactParams, SendSecretDocumentParams, SendSecretLocationParams, SendSecretMessageParams, SendSecretPhotoParams, SendSecretStickerParams, SendSecretVenueParams, SendSecretVideoNoteParams, SendSecretVideoParams, SendSecretVoiceParams } from "./0_params.js";
|
|
4
4
|
import type { UpdateProcessor } from "./0_update_processor.js";
|
|
5
5
|
import type { C as C_ } from "./1_types.js";
|
|
6
6
|
import type { FileManager } from "./2_file_manager.js";
|
|
@@ -15,10 +15,19 @@ export declare class SecretChatManager implements UpdateProcessor<SecretChatMana
|
|
|
15
15
|
loadSecretChats(): Promise<void>;
|
|
16
16
|
requestSecretChat(chatId: ID): Promise<import("../3_types.js").SecretChat>;
|
|
17
17
|
acceptSecretChat(id: number): Promise<import("../3_types.js").SecretChat>;
|
|
18
|
+
endSecretChat(id: number, params?: EndSecretChatParams): Promise<import("../3_types.js").SecretChat>;
|
|
18
19
|
sendSecretMessage(id: number, text: string, params?: SendSecretMessageParams): Promise<void>;
|
|
19
20
|
sendSecretLocation(id: number, latitude: number, longitude: number, params?: SendSecretLocationParams): Promise<void>;
|
|
20
21
|
sendSecretVenue(id: number, latitude: number, longitude: number, title: string, address: string, params?: SendSecretVenueParams): Promise<void>;
|
|
21
22
|
sendSecretContact(id: number, firstName: string, phoneNumber: string, params?: SendSecretContactParams): Promise<void>;
|
|
23
|
+
sendSecretDocument(id: number, document: FileSource, params?: SendSecretDocumentParams): Promise<void>;
|
|
24
|
+
sendSecretVideo(id: number, video: FileSource, params?: SendSecretVideoParams): Promise<void>;
|
|
25
|
+
sendSecretVideoNote(id: number, videoNote: FileSource, params?: SendSecretVideoNoteParams): Promise<void>;
|
|
26
|
+
sendSecretAudio(id: number, audio: FileSource, params?: SendSecretAudioParams): Promise<void>;
|
|
27
|
+
sendSecretVoice(id: number, voice: FileSource, params?: SendSecretVoiceParams): Promise<void>;
|
|
28
|
+
sendSecretAnimation(id: number, animation: FileSource, params?: SendSecretAnimationParams): Promise<void>;
|
|
29
|
+
sendSecretPhoto(id: number, photo: FileSource, params?: SendSecretPhotoParams): Promise<void>;
|
|
30
|
+
sendSecretSticker(id: number, sticker: Sticker, params?: SendSecretStickerParams): Promise<void>;
|
|
22
31
|
canHandleUpdate(update: Api.Update): update is SecretChatManagerUpdate;
|
|
23
32
|
handleUpdate(update: SecretChatManagerUpdate): Promise<Update | null>;
|
|
24
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"3_secret_chat_manager.d.ts","sourceRoot":"","sources":["../../src/client/3_secret_chat_manager.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"3_secret_chat_manager.d.ts","sourceRoot":"","sources":["../../src/client/3_secret_chat_manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -64,6 +64,7 @@ const _0_secret_chat_js_1 = require("../types/0_secret_chat.js");
|
|
|
64
64
|
const _2_secret_message_js_1 = require("../types/2_secret_message.js");
|
|
65
65
|
const _0_password_js_1 = require("./0_password.js");
|
|
66
66
|
const _0_secret_chat_state_js_1 = require("./0_secret_chat_state.js");
|
|
67
|
+
const _0_utilities_js_1 = require("./0_utilities.js");
|
|
67
68
|
const secretChatManagerUpdates = [
|
|
68
69
|
"updateEncryption",
|
|
69
70
|
"updateNewEncryptedMessage",
|
|
@@ -198,6 +199,19 @@ class SecretChatManager {
|
|
|
198
199
|
state.encryptedChat = result;
|
|
199
200
|
return (0, _0_secret_chat_js_1.constructSecretChat)(result);
|
|
200
201
|
}
|
|
202
|
+
async endSecretChat(id, params) {
|
|
203
|
+
this.#c.storage.assertUser("endSecretChat");
|
|
204
|
+
const state = this.#getSecretChatState(id);
|
|
205
|
+
switch (state.encryptedChat._) {
|
|
206
|
+
case "encryptedChatEmpty":
|
|
207
|
+
case "encryptedChatDiscarded":
|
|
208
|
+
throw new _0_errors_js_1.InputError("The secret chat has already ended.");
|
|
209
|
+
}
|
|
210
|
+
await this.#c.invoke({ _: "messages.discardEncryption", chat_id: state.encryptedChat.id, delete_history: params?.isHistoryDeleted || undefined });
|
|
211
|
+
state.encryptedChat = { _: "encryptedChatDiscarded", id: state.encryptedChat.id, history_deleted: params?.isHistoryDeleted || undefined };
|
|
212
|
+
await state.commit(this.#c.messageStorage.storage);
|
|
213
|
+
return (0, _0_secret_chat_js_1.constructSecretChat)(state.encryptedChat);
|
|
214
|
+
}
|
|
201
215
|
#getNextOutSeqNo(id, isCreator) {
|
|
202
216
|
const state = this.#getSecretChatState(id);
|
|
203
217
|
const rawOutSeqNo = state.outSeqNo;
|
|
@@ -288,23 +302,300 @@ class SecretChatManager {
|
|
|
288
302
|
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_);
|
|
289
303
|
await this.#postSendMessage(state);
|
|
290
304
|
}
|
|
305
|
+
#generateKeyIv() {
|
|
306
|
+
const key = dntShim.crypto.getRandomValues(new Uint8Array(32));
|
|
307
|
+
const iv = dntShim.crypto.getRandomValues(new Uint8Array(32));
|
|
308
|
+
return [key, iv];
|
|
309
|
+
}
|
|
310
|
+
async sendSecretDocument(id, document, params) {
|
|
311
|
+
this.#c.storage.assertUser("sendSecretDocument");
|
|
312
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
313
|
+
const [key, iv] = this.#generateKeyIv();
|
|
314
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(document, params, null, true, { key, iv });
|
|
315
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
316
|
+
const decryptedMessage = {
|
|
317
|
+
_: "decryptedMessage",
|
|
318
|
+
message: params?.caption ?? "",
|
|
319
|
+
entities: params?.entities?.length ? params.entities.map(_3_types_js_1.secretMessageEntityToTlObject) : undefined,
|
|
320
|
+
random_id,
|
|
321
|
+
ttl: params?.ttl ?? 0,
|
|
322
|
+
silent: params?.isSilent || undefined,
|
|
323
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
324
|
+
via_bot_name: params?.viaBot,
|
|
325
|
+
media: {
|
|
326
|
+
_: "decryptedMessageMediaDocument",
|
|
327
|
+
key,
|
|
328
|
+
iv,
|
|
329
|
+
caption: "",
|
|
330
|
+
size: BigInt(fileSize),
|
|
331
|
+
mime_type: params?.mimeType ?? "",
|
|
332
|
+
attributes: params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : [],
|
|
333
|
+
thumb: new Uint8Array(),
|
|
334
|
+
thumb_w: 0,
|
|
335
|
+
thumb_h: 0,
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
339
|
+
await this.#postSendMessage(state);
|
|
340
|
+
}
|
|
341
|
+
async sendSecretVideo(id, video, params) {
|
|
342
|
+
this.#c.storage.assertUser("sendSecretVideo");
|
|
343
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
344
|
+
const [key, iv] = this.#generateKeyIv();
|
|
345
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(video, params, null, true, { key, iv });
|
|
346
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
347
|
+
const decryptedMessage = {
|
|
348
|
+
_: "decryptedMessage",
|
|
349
|
+
message: params?.caption ?? "",
|
|
350
|
+
entities: params?.entities?.length ? params.entities.map(_3_types_js_1.secretMessageEntityToTlObject) : undefined,
|
|
351
|
+
random_id,
|
|
352
|
+
ttl: params?.ttl ?? 0,
|
|
353
|
+
silent: params?.isSilent || undefined,
|
|
354
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
355
|
+
via_bot_name: params?.viaBot,
|
|
356
|
+
media: {
|
|
357
|
+
_: "decryptedMessageMediaDocument",
|
|
358
|
+
key,
|
|
359
|
+
iv,
|
|
360
|
+
caption: "",
|
|
361
|
+
size: BigInt(fileSize),
|
|
362
|
+
mime_type: params?.mimeType ?? "",
|
|
363
|
+
attributes: [
|
|
364
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
365
|
+
{ _: "documentAttributeVideo", duration: params?.duration ?? 0, w: params?.width ?? 0, h: params?.height ?? 0 },
|
|
366
|
+
],
|
|
367
|
+
thumb: new Uint8Array(),
|
|
368
|
+
thumb_w: 0,
|
|
369
|
+
thumb_h: 0,
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
373
|
+
await this.#postSendMessage(state);
|
|
374
|
+
}
|
|
375
|
+
async sendSecretVideoNote(id, videoNote, params) {
|
|
376
|
+
this.#c.storage.assertUser("sendSecretVideoNote");
|
|
377
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
378
|
+
const [key, iv] = this.#generateKeyIv();
|
|
379
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(videoNote, params, null, true, { key, iv });
|
|
380
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
381
|
+
const decryptedMessage = {
|
|
382
|
+
_: "decryptedMessage",
|
|
383
|
+
message: params?.caption ?? "",
|
|
384
|
+
entities: params?.entities?.length ? params.entities.map(_3_types_js_1.secretMessageEntityToTlObject) : undefined,
|
|
385
|
+
random_id,
|
|
386
|
+
ttl: params?.ttl ?? 0,
|
|
387
|
+
silent: params?.isSilent || undefined,
|
|
388
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
389
|
+
via_bot_name: params?.viaBot,
|
|
390
|
+
media: {
|
|
391
|
+
_: "decryptedMessageMediaDocument",
|
|
392
|
+
key,
|
|
393
|
+
iv,
|
|
394
|
+
caption: "",
|
|
395
|
+
size: BigInt(fileSize),
|
|
396
|
+
mime_type: params?.mimeType ?? "",
|
|
397
|
+
attributes: [
|
|
398
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
399
|
+
{ _: "documentAttributeVideo", duration: params?.duration ?? 0, w: params?.length ?? 0, h: params?.length ?? 0, round_message: true },
|
|
400
|
+
],
|
|
401
|
+
thumb: new Uint8Array(),
|
|
402
|
+
thumb_w: 0,
|
|
403
|
+
thumb_h: 0,
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
407
|
+
await this.#postSendMessage(state);
|
|
408
|
+
}
|
|
409
|
+
async sendSecretAudio(id, audio, params) {
|
|
410
|
+
this.#c.storage.assertUser("sendSecretAudio");
|
|
411
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
412
|
+
const [key, iv] = this.#generateKeyIv();
|
|
413
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(audio, params, null, true, { key, iv });
|
|
414
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
415
|
+
const decryptedMessage = {
|
|
416
|
+
_: "decryptedMessage",
|
|
417
|
+
message: params?.caption ?? "",
|
|
418
|
+
entities: params?.entities?.length ? params.entities.map(_3_types_js_1.secretMessageEntityToTlObject) : undefined,
|
|
419
|
+
random_id,
|
|
420
|
+
ttl: params?.ttl ?? 0,
|
|
421
|
+
silent: params?.isSilent || undefined,
|
|
422
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
423
|
+
via_bot_name: params?.viaBot,
|
|
424
|
+
media: {
|
|
425
|
+
_: "decryptedMessageMediaDocument",
|
|
426
|
+
key,
|
|
427
|
+
iv,
|
|
428
|
+
caption: "",
|
|
429
|
+
size: BigInt(fileSize),
|
|
430
|
+
mime_type: params?.mimeType ?? "",
|
|
431
|
+
attributes: [
|
|
432
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
433
|
+
{ _: "documentAttributeAudio", duration: params?.duration ?? 0, title: params?.title, performer: params?.performer },
|
|
434
|
+
],
|
|
435
|
+
thumb: new Uint8Array(),
|
|
436
|
+
thumb_w: 0,
|
|
437
|
+
thumb_h: 0,
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
441
|
+
await this.#postSendMessage(state);
|
|
442
|
+
}
|
|
443
|
+
async sendSecretVoice(id, voice, params) {
|
|
444
|
+
this.#c.storage.assertUser("sendSecretVoice");
|
|
445
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
446
|
+
const [key, iv] = this.#generateKeyIv();
|
|
447
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(voice, params, null, true, { key, iv });
|
|
448
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
449
|
+
const decryptedMessage = {
|
|
450
|
+
_: "decryptedMessage",
|
|
451
|
+
message: params?.caption ?? "",
|
|
452
|
+
entities: params?.entities?.length ? params.entities.map(_3_types_js_1.secretMessageEntityToTlObject) : undefined,
|
|
453
|
+
random_id,
|
|
454
|
+
ttl: params?.ttl ?? 0,
|
|
455
|
+
silent: params?.isSilent || undefined,
|
|
456
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
457
|
+
via_bot_name: params?.viaBot,
|
|
458
|
+
media: {
|
|
459
|
+
_: "decryptedMessageMediaDocument",
|
|
460
|
+
key,
|
|
461
|
+
iv,
|
|
462
|
+
caption: "",
|
|
463
|
+
size: BigInt(fileSize),
|
|
464
|
+
mime_type: params?.mimeType ?? "",
|
|
465
|
+
attributes: [
|
|
466
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
467
|
+
{ _: "documentAttributeAudio", duration: params?.duration ?? 0, voice: true },
|
|
468
|
+
],
|
|
469
|
+
thumb: new Uint8Array(),
|
|
470
|
+
thumb_w: 0,
|
|
471
|
+
thumb_h: 0,
|
|
472
|
+
},
|
|
473
|
+
};
|
|
474
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
475
|
+
await this.#postSendMessage(state);
|
|
476
|
+
}
|
|
477
|
+
async sendSecretAnimation(id, animation, params) {
|
|
478
|
+
this.#c.storage.assertUser("sendSecretAnimation");
|
|
479
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
480
|
+
const [key, iv] = this.#generateKeyIv();
|
|
481
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(animation, params, null, true, { key, iv });
|
|
482
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
483
|
+
const decryptedMessage = {
|
|
484
|
+
_: "decryptedMessage",
|
|
485
|
+
message: params?.caption ?? "",
|
|
486
|
+
entities: params?.entities?.length ? params.entities.map(_3_types_js_1.secretMessageEntityToTlObject) : undefined,
|
|
487
|
+
random_id,
|
|
488
|
+
ttl: params?.ttl ?? 0,
|
|
489
|
+
silent: params?.isSilent || undefined,
|
|
490
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
491
|
+
via_bot_name: params?.viaBot,
|
|
492
|
+
media: {
|
|
493
|
+
_: "decryptedMessageMediaDocument",
|
|
494
|
+
key,
|
|
495
|
+
iv,
|
|
496
|
+
caption: "",
|
|
497
|
+
size: BigInt(fileSize),
|
|
498
|
+
mime_type: params?.mimeType ?? "",
|
|
499
|
+
attributes: [
|
|
500
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
501
|
+
{ _: "documentAttributeVideo", duration: params?.duration ?? 0, w: params?.width ?? 0, h: params?.height ?? 0 },
|
|
502
|
+
{ _: "documentAttributeAnimated" },
|
|
503
|
+
],
|
|
504
|
+
thumb: new Uint8Array(),
|
|
505
|
+
thumb_w: 0,
|
|
506
|
+
thumb_h: 0,
|
|
507
|
+
},
|
|
508
|
+
};
|
|
509
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
510
|
+
await this.#postSendMessage(state);
|
|
511
|
+
}
|
|
512
|
+
async sendSecretPhoto(id, photo, params) {
|
|
513
|
+
this.#c.storage.assertUser("sendSecretPhoto");
|
|
514
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
515
|
+
const [key, iv] = this.#generateKeyIv();
|
|
516
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(photo, params, (0, _0_utilities_js_1.checkPhotoName)(params), true, { key, iv });
|
|
517
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
518
|
+
const decryptedMessage = {
|
|
519
|
+
_: "decryptedMessage",
|
|
520
|
+
message: params?.caption ?? "",
|
|
521
|
+
entities: params?.entities?.length ? params.entities.map(_3_types_js_1.secretMessageEntityToTlObject) : undefined,
|
|
522
|
+
random_id,
|
|
523
|
+
ttl: params?.ttl ?? 0,
|
|
524
|
+
silent: params?.isSilent || undefined,
|
|
525
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
526
|
+
via_bot_name: params?.viaBot,
|
|
527
|
+
media: {
|
|
528
|
+
_: "decryptedMessageMediaPhoto",
|
|
529
|
+
key,
|
|
530
|
+
iv,
|
|
531
|
+
caption: "",
|
|
532
|
+
size: fileSize,
|
|
533
|
+
w: params?.width ?? 0,
|
|
534
|
+
h: params?.height ?? 0,
|
|
535
|
+
thumb: new Uint8Array(),
|
|
536
|
+
thumb_w: 0,
|
|
537
|
+
thumb_h: 0,
|
|
538
|
+
},
|
|
539
|
+
};
|
|
540
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
541
|
+
await this.#postSendMessage(state);
|
|
542
|
+
}
|
|
543
|
+
async sendSecretSticker(id, sticker, params) {
|
|
544
|
+
this.#c.storage.assertUser("sendSecretSticker");
|
|
545
|
+
if (!sticker.setName) {
|
|
546
|
+
throw new _0_errors_js_1.InputError("This sticker cannot be sent to a secret chat.");
|
|
547
|
+
}
|
|
548
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
549
|
+
let inputEncryptedFile;
|
|
550
|
+
const fileID = (0, _3_types_js_1.deserializeFileId)(sticker.fileId);
|
|
551
|
+
if (fileID.location.type !== "common") {
|
|
552
|
+
(0, _0_deps_js_1.unreachable)();
|
|
553
|
+
}
|
|
554
|
+
const media = {
|
|
555
|
+
_: "decryptedMessageMediaExternalDocument",
|
|
556
|
+
dc_id: fileID.dcId,
|
|
557
|
+
access_hash: fileID.location.accessHash,
|
|
558
|
+
attributes: [
|
|
559
|
+
{ _: "documentAttributeImageSize", w: sticker.width, h: sticker.height },
|
|
560
|
+
{ _: "documentAttributeSticker", alt: sticker.emoji ?? "", stickerset: { _: "inputStickerSetShortName", short_name: sticker.setName } },
|
|
561
|
+
],
|
|
562
|
+
date: 0,
|
|
563
|
+
id: fileID.location.id,
|
|
564
|
+
size: sticker.fileSize ?? 0,
|
|
565
|
+
thumb: { _: "photoSizeEmpty", type: "s" },
|
|
566
|
+
mime_type: sticker.isVideo ? "video/webm" : sticker.isAnimated ? "application/x-tgsticker" : "image/webp",
|
|
567
|
+
};
|
|
568
|
+
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
569
|
+
const decryptedMessage = {
|
|
570
|
+
_: "decryptedMessage",
|
|
571
|
+
message: "",
|
|
572
|
+
random_id,
|
|
573
|
+
ttl: params?.ttl ?? 0,
|
|
574
|
+
silent: params?.isSilent || undefined,
|
|
575
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
576
|
+
via_bot_name: params?.viaBot,
|
|
577
|
+
media,
|
|
578
|
+
};
|
|
579
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
580
|
+
await this.#postSendMessage(state);
|
|
581
|
+
}
|
|
291
582
|
#sendTails = new Map();
|
|
292
|
-
async #sendMessage(message, encryptedChat, authKey, authKeyId) {
|
|
583
|
+
async #sendMessage(message, encryptedChat, authKey, authKeyId, file) {
|
|
293
584
|
try {
|
|
294
|
-
await this.#sendMessageInner(message, encryptedChat, authKey, authKeyId);
|
|
585
|
+
await this.#sendMessageInner(message, encryptedChat, authKey, authKeyId, file);
|
|
295
586
|
}
|
|
296
587
|
finally {
|
|
297
588
|
await this.#getSecretChatState(encryptedChat.id).commit(this.#c.messageStorage.storage);
|
|
298
589
|
}
|
|
299
590
|
}
|
|
300
|
-
async #sendMessageInner(message, encryptedChat, authKey, authKeyId) {
|
|
591
|
+
async #sendMessageInner(message, encryptedChat, authKey, authKeyId, file) {
|
|
301
592
|
const previous = this.#sendTails.get(encryptedChat.id) ?? Promise.resolve();
|
|
302
593
|
const { promise, resolve } = Promise.withResolvers();
|
|
303
594
|
const tail = previous.then(() => promise);
|
|
304
595
|
this.#sendTails.set(encryptedChat.id, tail);
|
|
305
596
|
await previous;
|
|
306
597
|
try {
|
|
307
|
-
await this.#sendMessageUnlocked(message, encryptedChat, authKey, authKeyId);
|
|
598
|
+
await this.#sendMessageUnlocked(message, encryptedChat, authKey, authKeyId, file);
|
|
308
599
|
}
|
|
309
600
|
finally {
|
|
310
601
|
resolve();
|
|
@@ -313,15 +604,35 @@ class SecretChatManager {
|
|
|
313
604
|
}
|
|
314
605
|
}
|
|
315
606
|
}
|
|
316
|
-
async #sendMessageUnlocked(message, encryptedChat, authKey, authKeyId) {
|
|
317
|
-
const random_id = (0, _1_utilities_js_1.getRandomId)();
|
|
607
|
+
async #sendMessageUnlocked(message, encryptedChat, authKey, authKeyId, file) {
|
|
318
608
|
const isCreator = Number(encryptedChat.admin_id) === await this.#c.getSelfId();
|
|
319
609
|
const out_seq_no = this.#getNextOutSeqNo(encryptedChat.id, isCreator);
|
|
320
610
|
const in_seq_no = this.#getInSeqNo(encryptedChat.id, isCreator);
|
|
321
611
|
const decryptedMessageLayer = { _: "decryptedMessageLayer", in_seq_no, layer: 144, message, out_seq_no, random_bytes: dntShim.crypto.getRandomValues(new Uint8Array(15)) };
|
|
322
612
|
const data = await this.#encryptMessage(isCreator, authKeyId, authKey, decryptedMessageLayer);
|
|
323
613
|
this.#getSecretChatState(encryptedChat.id).outgoingMessages.set((out_seq_no - (isCreator ? 1 : 0)) / 2, data);
|
|
324
|
-
|
|
614
|
+
if (file) {
|
|
615
|
+
const result = await this.#c.invoke({
|
|
616
|
+
_: "messages.sendEncryptedFile",
|
|
617
|
+
silent: _2_tl_js_1.SecretChats.is("decryptedMessage", message) && message.silent ? true : undefined,
|
|
618
|
+
peer: { _: "inputEncryptedChat", chat_id: encryptedChat.id, access_hash: encryptedChat.access_hash },
|
|
619
|
+
random_id: message.random_id,
|
|
620
|
+
data,
|
|
621
|
+
file,
|
|
622
|
+
});
|
|
623
|
+
if (!_2_tl_js_1.Api.is("messages.sentEncryptedFile", result) || !_2_tl_js_1.Api.is("encryptedFile", result.file) || result.file.size <= 0n) {
|
|
624
|
+
throw new _0_errors_js_1.InputError("Telegram did not attach the encrypted file to the secret message.");
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
await this.#c.invoke({
|
|
629
|
+
_: "messages.sendEncrypted",
|
|
630
|
+
silent: _2_tl_js_1.SecretChats.is("decryptedMessage", message) && message.silent ? true : undefined,
|
|
631
|
+
peer: { _: "inputEncryptedChat", chat_id: encryptedChat.id, access_hash: encryptedChat.access_hash },
|
|
632
|
+
random_id: message.random_id,
|
|
633
|
+
data,
|
|
634
|
+
});
|
|
635
|
+
}
|
|
325
636
|
const state = this.#getSecretChatState(encryptedChat.id);
|
|
326
637
|
if ((0, _0_deps_js_1.equals)(state.authKeyId_, authKeyId)) {
|
|
327
638
|
++state.authKeyUseCount;
|
|
@@ -681,7 +992,7 @@ class SecretChatManager {
|
|
|
681
992
|
authKeyId = state.previousAuthKeyId_;
|
|
682
993
|
}
|
|
683
994
|
const decryptedMessage = await this.#decryptMessage(authKeyId, authKey, isCreator, update.message.bytes);
|
|
684
|
-
this.#L.debug("received", decryptedMessage);
|
|
995
|
+
this.#L.debug("received", (0, _2_tl_js_1.repr)(decryptedMessage));
|
|
685
996
|
if (_2_tl_js_1.SecretChats.is("decryptedMessageLayer", decryptedMessage)) {
|
|
686
997
|
const x = isCreator ? 0 : 1;
|
|
687
998
|
const rawOutSeqNo = (decryptedMessage.out_seq_no - x) / 2;
|