@mtkruto/node 0.171.0 → 0.180.0
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 +52 -0
- package/esm/client/0_params.d.ts.map +1 -1
- package/esm/client/1_client_generic.d.ts +64 -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 +77 -27
- package/esm/client/3_secret_chat_manager.d.ts +10 -2
- package/esm/client/3_secret_chat_manager.d.ts.map +1 -1
- package/esm/client/3_secret_chat_manager.js +274 -6
- package/esm/client/4_context.d.ts +3 -1
- package/esm/client/4_context.d.ts.map +1 -1
- package/esm/client/4_context.js +5 -0
- package/esm/client/6_client.d.ts +64 -1
- package/esm/client/6_client.d.ts.map +1 -1
- package/esm/client/6_client.js +79 -0
- package/esm/client/6_client_dispatcher.d.ts +64 -1
- package/esm/client/6_client_dispatcher.d.ts.map +1 -1
- package/esm/client/6_client_dispatcher.js +79 -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 +52 -0
- package/script/client/0_params.d.ts.map +1 -1
- package/script/client/1_client_generic.d.ts +64 -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 +74 -24
- package/script/client/3_secret_chat_manager.d.ts +10 -2
- package/script/client/3_secret_chat_manager.d.ts.map +1 -1
- package/script/client/3_secret_chat_manager.js +274 -6
- package/script/client/4_context.d.ts +3 -1
- package/script/client/4_context.d.ts.map +1 -1
- package/script/client/4_context.js +5 -0
- package/script/client/6_client.d.ts +64 -1
- package/script/client/6_client.d.ts.map +1 -1
- package/script/client/6_client.js +79 -0
- package/script/client/6_client_dispatcher.d.ts +64 -1
- package/script/client/6_client_dispatcher.d.ts.map +1 -1
- package/script/client/6_client_dispatcher.js +79 -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
|
@@ -19,16 +19,16 @@ var _a;
|
|
|
19
19
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
20
20
|
*/
|
|
21
21
|
import * as dntShim from "../_dnt.shims.js";
|
|
22
|
-
import { AssertionError, basename, decodeHex, delay, extension, extname, ige256Decrypt, isAbsolute, join, MINUTE, SECOND, toFileUrl, unreachable } from "../0_deps.js";
|
|
22
|
+
import { AssertionError, basename, concat, crypto, decodeHex, delay, extension, extname, ige256Decrypt, ige256Encrypt, isAbsolute, join, MINUTE, SECOND, toFileUrl, unreachable } from "../0_deps.js";
|
|
23
23
|
import { InputError } from "../0_errors.js";
|
|
24
|
-
import { getLogger, getRandomId, iterateReadableStream, kilobyte, megabyte, mod, PartStream } from "../1_utilities.js";
|
|
24
|
+
import { getLogger, getRandomId, intFromBytes, iterateReadableStream, kilobyte, megabyte, mod, PartStream } from "../1_utilities.js";
|
|
25
25
|
import { Api } from "../2_tl.js";
|
|
26
26
|
import { TimeTooBig, TimeTooSmall } from "../3_errors.js";
|
|
27
27
|
import { getDc } from "../3_transport.js";
|
|
28
28
|
import { constructSticker, deserializeFileId, FileType, PhotoSourceType, serializeFileId, toUniqueFileId } from "../3_types.js";
|
|
29
29
|
import { DOWNLOAD_MAX_CHUNK_SIZE, STICKER_SET_NAME_TTL } from "../4_constants.js";
|
|
30
30
|
import { FloodWait, StickersetInvalid } from "../4_errors.js";
|
|
31
|
-
import { UPLOAD_REQUEST_PER_CONNECTION } from "./0_utilities.js";
|
|
31
|
+
import { DOWNLOAD_POOL_SIZE, DOWNLOAD_REQUEST_PER_CONNECTION, UPLOAD_REQUEST_PER_CONNECTION } from "./0_utilities.js";
|
|
32
32
|
export class FileManager {
|
|
33
33
|
#c;
|
|
34
34
|
#Lupload;
|
|
@@ -48,7 +48,7 @@ export class FileManager {
|
|
|
48
48
|
this.#progressIds.add(id);
|
|
49
49
|
return Promise.resolve(String(id));
|
|
50
50
|
}
|
|
51
|
-
async upload(file, params, checkName, allowStream = true) {
|
|
51
|
+
async upload(file, params, checkName, allowStream = true, encryptionInformation) {
|
|
52
52
|
if (params?.progressId !== undefined && !this.#progressIds.has(BigInt(params.progressId))) {
|
|
53
53
|
throw new InputError("Invalid progressId.");
|
|
54
54
|
}
|
|
@@ -72,15 +72,28 @@ export class FileManager {
|
|
|
72
72
|
this.#Lupload.debug("uploading " + whatIsUploaded + " with chunk size of " + chunkSize + " and pool size of " + poolSize + " and file ID of " + fileId);
|
|
73
73
|
let result;
|
|
74
74
|
if (contents instanceof Uint8Array) {
|
|
75
|
-
result = await this.#uploadBuffer(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal);
|
|
75
|
+
result = await this.#uploadBuffer(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal, encryptionInformation);
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
78
|
-
result = await this.#uploadStream(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal);
|
|
78
|
+
result = await this.#uploadStream(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal, encryptionInformation);
|
|
79
79
|
}
|
|
80
80
|
this.#Lupload.debug(`[${fileId}] uploaded ` + result.parts + " part(s)");
|
|
81
81
|
if (checkName) {
|
|
82
82
|
name = checkName(name, result.firstPart);
|
|
83
83
|
}
|
|
84
|
+
if (encryptionInformation) {
|
|
85
|
+
const digest = new Uint8Array(await crypto.subtle.digest("MD5", concat([encryptionInformation.key, encryptionInformation.iv])));
|
|
86
|
+
const right = digest.subarray(4, 8);
|
|
87
|
+
const key_fingerprint = Number(intFromBytes(digest.subarray(0, 4).map((v, i) => v ^ right[i])));
|
|
88
|
+
if (result.isSmall) {
|
|
89
|
+
const inputEncryptedFile = { _: "inputEncryptedFileUploaded", id: fileId, parts: result.parts, key_fingerprint, md5_checksum: "" };
|
|
90
|
+
return { inputEncryptedFile, fileSize: result.fileSize };
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const inputEncryptedFile = { _: "inputEncryptedFileBigUploaded", id: fileId, parts: result.parts, key_fingerprint };
|
|
94
|
+
return { inputEncryptedFile, fileSize: result.fileSize };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
84
97
|
if (result.isSmall) {
|
|
85
98
|
return { _: "inputFile", id: fileId, name, parts: result.parts, md5_checksum: "" };
|
|
86
99
|
}
|
|
@@ -88,17 +101,29 @@ export class FileManager {
|
|
|
88
101
|
return { _: "inputFileBig", id: fileId, name, parts: result.parts };
|
|
89
102
|
}
|
|
90
103
|
}
|
|
91
|
-
async #uploadStream(stream, fileId, mustTrackProgress, chunkSize, poolSize, signal) {
|
|
104
|
+
async #uploadStream(stream, fileId, mustTrackProgress, chunkSize, poolSize, signal, encryptionInformation) {
|
|
92
105
|
let part;
|
|
93
106
|
let promises = new Array();
|
|
94
107
|
let ms = 0.05;
|
|
95
108
|
let uploaded = 0;
|
|
96
109
|
let firstPart;
|
|
110
|
+
let iv = encryptionInformation?.iv;
|
|
111
|
+
let fileSize = 0;
|
|
97
112
|
for await (part of iterateReadableStream(stream.pipeThrough(new PartStream(chunkSize)))) {
|
|
98
113
|
if (!part.isSmall && part.part > 0) {
|
|
99
114
|
await delay(ms);
|
|
100
115
|
ms = Math.max(ms * .8, 0.003);
|
|
101
116
|
}
|
|
117
|
+
if (encryptionInformation) {
|
|
118
|
+
fileSize += part.bytes.byteLength;
|
|
119
|
+
if (part.bytes.byteLength % 16 !== 0) {
|
|
120
|
+
part.bytes = concat([part.bytes, crypto.getRandomValues(new Uint8Array((16 - part.bytes.length % 16) % 16))]);
|
|
121
|
+
}
|
|
122
|
+
const right = part.bytes.subarray(-16);
|
|
123
|
+
part.bytes = ige256Encrypt(part.bytes, encryptionInformation.key, iv);
|
|
124
|
+
const left = part.bytes.subarray(-16);
|
|
125
|
+
iv = concat([left, right]);
|
|
126
|
+
}
|
|
102
127
|
if (!firstPart) {
|
|
103
128
|
firstPart = part.bytes;
|
|
104
129
|
}
|
|
@@ -131,9 +156,9 @@ export class FileManager {
|
|
|
131
156
|
isUploaded: true,
|
|
132
157
|
},
|
|
133
158
|
});
|
|
134
|
-
return { isSmall: part.isSmall, parts: part.totalParts, firstPart };
|
|
159
|
+
return { isSmall: part.isSmall, parts: part.totalParts, firstPart, fileSize };
|
|
135
160
|
}
|
|
136
|
-
async #uploadBuffer(buffer, fileId, mustTrackProgress, chunkSize, poolSize, signal) {
|
|
161
|
+
async #uploadBuffer(buffer, fileId, mustTrackProgress, chunkSize, poolSize, signal, encryptionInformation) {
|
|
137
162
|
const isBig = buffer.byteLength > _a.#BIG_FILE_THRESHOLD;
|
|
138
163
|
const partCount = Math.ceil(buffer.byteLength / chunkSize);
|
|
139
164
|
let promises = new Array();
|
|
@@ -141,15 +166,27 @@ export class FileManager {
|
|
|
141
166
|
let ms = 0.05;
|
|
142
167
|
let uploaded = 0;
|
|
143
168
|
let firstPart;
|
|
169
|
+
let iv = encryptionInformation?.iv;
|
|
170
|
+
let fileSize = 0;
|
|
144
171
|
main: for (let part = 0; part < partCount;) {
|
|
145
172
|
for (let i = 0; i < poolSize; ++i) {
|
|
146
173
|
for (let i = 0; i < UPLOAD_REQUEST_PER_CONNECTION; ++i) {
|
|
147
174
|
const start = part * chunkSize;
|
|
148
175
|
const end = start + chunkSize;
|
|
149
|
-
|
|
176
|
+
let bytes = buffer.subarray(start, end);
|
|
150
177
|
if (!bytes.byteLength) {
|
|
151
178
|
break main;
|
|
152
179
|
}
|
|
180
|
+
if (encryptionInformation) {
|
|
181
|
+
fileSize += bytes.byteLength;
|
|
182
|
+
if (bytes.byteLength % 16 !== 0) {
|
|
183
|
+
bytes = concat([bytes, crypto.getRandomValues(new Uint8Array((16 - bytes.length % 16) % 16))]);
|
|
184
|
+
}
|
|
185
|
+
const right = bytes.subarray(-16);
|
|
186
|
+
bytes = ige256Encrypt(bytes, encryptionInformation.key, iv);
|
|
187
|
+
const left = bytes.subarray(-16);
|
|
188
|
+
iv = concat([left, right]);
|
|
189
|
+
}
|
|
153
190
|
if (!started) {
|
|
154
191
|
started = true;
|
|
155
192
|
}
|
|
@@ -193,7 +230,7 @@ export class FileManager {
|
|
|
193
230
|
isUploaded: true,
|
|
194
231
|
},
|
|
195
232
|
});
|
|
196
|
-
return { isSmall: !isBig, parts: partCount, firstPart };
|
|
233
|
+
return { isSmall: !isBig, parts: partCount, firstPart, fileSize };
|
|
197
234
|
}
|
|
198
235
|
async #uploadPart(fileId, partCount, isBig, index, bytes, signal) {
|
|
199
236
|
let retryIn = 1;
|
|
@@ -363,27 +400,29 @@ export class FileManager {
|
|
|
363
400
|
let offset = params?.offset ? BigInt(params.offset) : 0n;
|
|
364
401
|
let part = 0;
|
|
365
402
|
let totalSize = 0;
|
|
366
|
-
|
|
403
|
+
const requestCount = DOWNLOAD_POOL_SIZE * DOWNLOAD_REQUEST_PER_CONNECTION;
|
|
404
|
+
let finished = false;
|
|
367
405
|
while (true) {
|
|
368
406
|
signal?.throwIfAborted();
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
try {
|
|
372
|
-
const file = await this.#c.invoke({ _: "upload.getFile", location, offset, limit }, { dc, type: "download" });
|
|
407
|
+
const results = await Promise.all(Array.from({ length: requestCount }, (_, i) => this.#downloadPart(location, offset + BigInt(i * limit), limit, dc, signal, id, part + i)));
|
|
408
|
+
for (const result of results) {
|
|
373
409
|
signal?.throwIfAborted();
|
|
374
|
-
if (Api.is("upload.file",
|
|
375
|
-
const downloadedSize =
|
|
376
|
-
|
|
410
|
+
if (Api.is("upload.file", result)) {
|
|
411
|
+
const downloadedSize = result.bytes.byteLength;
|
|
412
|
+
finished = downloadedSize < limit;
|
|
377
413
|
if (decryptionInformation) {
|
|
378
|
-
const
|
|
414
|
+
const left = result.bytes.subarray(-16);
|
|
415
|
+
const decryptedBytes = ige256Decrypt(result.bytes, decryptionInformation.key, decryptionInformation.iv);
|
|
416
|
+
const right = decryptedBytes.subarray(-16);
|
|
379
417
|
const remainingSize = Math.max(0, fileSize - totalSize);
|
|
380
|
-
|
|
381
|
-
totalSize +=
|
|
418
|
+
result.bytes = decryptedBytes.slice(0, remainingSize);
|
|
419
|
+
totalSize += result.bytes.byteLength;
|
|
382
420
|
finished = totalSize >= fileSize;
|
|
421
|
+
decryptionInformation.iv = concat([left, right]);
|
|
383
422
|
}
|
|
384
|
-
yield
|
|
423
|
+
yield result.bytes;
|
|
385
424
|
if (id !== null) {
|
|
386
|
-
await this.#c.storage.saveFilePart(id, part,
|
|
425
|
+
await this.#c.storage.saveFilePart(id, part, result.bytes);
|
|
387
426
|
signal?.throwIfAborted();
|
|
388
427
|
}
|
|
389
428
|
++part;
|
|
@@ -401,8 +440,19 @@ export class FileManager {
|
|
|
401
440
|
else {
|
|
402
441
|
unreachable();
|
|
403
442
|
}
|
|
404
|
-
|
|
405
|
-
|
|
443
|
+
}
|
|
444
|
+
if (finished) {
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
async #downloadPart(location, offset, limit, dc, signal, id, part) {
|
|
450
|
+
let retryIn = 1;
|
|
451
|
+
let errorCount = 0;
|
|
452
|
+
while (true) {
|
|
453
|
+
try {
|
|
454
|
+
signal?.throwIfAborted();
|
|
455
|
+
return await this.#c.invoke({ _: "upload.getFile", location, offset, limit }, { dc, type: "download" });
|
|
406
456
|
}
|
|
407
457
|
catch (err) {
|
|
408
458
|
if (typeof err === "object" && err instanceof AssertionError) {
|
|
@@ -411,7 +461,7 @@ export class FileManager {
|
|
|
411
461
|
++errorCount;
|
|
412
462
|
if (errorCount > 20) {
|
|
413
463
|
retryIn = 0;
|
|
414
|
-
errorCount =
|
|
464
|
+
errorCount = 20;
|
|
415
465
|
}
|
|
416
466
|
await this.#handleError(err, retryIn, `[${id}-${part + 1}]`);
|
|
417
467
|
signal?.throwIfAborted();
|
|
@@ -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 Update } from "../3_types.js";
|
|
3
|
+
import type { EndSecretChatParams, SendSecretAnimationParams, SendSecretAudioParams, SendSecretContactParams, SendSecretDocumentParams, SendSecretLocationParams, SendSecretMessageParams, SendSecretPhotoParams, 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,18 @@ 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>;
|
|
22
30
|
canHandleUpdate(update: Api.Update): update is SecretChatManagerUpdate;
|
|
23
31
|
handleUpdate(update: SecretChatManagerUpdate): Promise<Update | null>;
|
|
24
32
|
}
|
|
@@ -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,EAAsC,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,EAAiC,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;
|
|
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,EAAsC,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,EAAE,EAAiC,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAGrG,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGxU,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,UAAU,CAAE,SAAQ,EAAE;IACpB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,QAAA,MAAM,wBAAwB,4DAGpB,CAAC;AAEX,KAAK,uBAAuB,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAEpF,qBAAa,iBAAkB,YAAW,eAAe,CAAC,uBAAuB,EAAE,IAAI,CAAC;;gBAI1E,CAAC,EAAE,CAAC;IAKV,eAAe;IA6Ef,iBAAiB,CAAC,MAAM,EAAE,EAAE;IA2B5B,gBAAgB,CAAC,EAAE,EAAE,MAAM;IAgD3B,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB;IAyCtD,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,uBAAuB;IAoB5E,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,wBAAwB;IAoBrG,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,qBAAqB;IAoB/H,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,uBAAuB;IA0BtG,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,wBAAwB;IAoCtF,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,qBAAqB;IAuC7E,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,yBAAyB;IAuCzF,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,qBAAqB;IAuC7E,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,qBAAqB;IAuC7E,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,yBAAyB;IAwCzF,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,qBAAqB;IAggBnF,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,IAAI,uBAAuB;IAIhE,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAuG5E"}
|
|
@@ -28,6 +28,7 @@ import { constructSecretChat } from "../types/0_secret_chat.js";
|
|
|
28
28
|
import { constructSecretMessage } from "../types/2_secret_message.js";
|
|
29
29
|
import { isGoodModExpFirst, isSafePrime } from "./0_password.js";
|
|
30
30
|
import { SecretChatState } from "./0_secret_chat_state.js";
|
|
31
|
+
import { checkPhotoName } from "./0_utilities.js";
|
|
31
32
|
const secretChatManagerUpdates = [
|
|
32
33
|
"updateEncryption",
|
|
33
34
|
"updateNewEncryptedMessage",
|
|
@@ -162,6 +163,19 @@ export class SecretChatManager {
|
|
|
162
163
|
state.encryptedChat = result;
|
|
163
164
|
return constructSecretChat(result);
|
|
164
165
|
}
|
|
166
|
+
async endSecretChat(id, params) {
|
|
167
|
+
this.#c.storage.assertUser("endSecretChat");
|
|
168
|
+
const state = this.#getSecretChatState(id);
|
|
169
|
+
switch (state.encryptedChat._) {
|
|
170
|
+
case "encryptedChatEmpty":
|
|
171
|
+
case "encryptedChatDiscarded":
|
|
172
|
+
throw new InputError("The secret chat has already ended.");
|
|
173
|
+
}
|
|
174
|
+
await this.#c.invoke({ _: "messages.discardEncryption", chat_id: state.encryptedChat.id, delete_history: params?.isHistoryDeleted || undefined });
|
|
175
|
+
state.encryptedChat = { _: "encryptedChatDiscarded", id: state.encryptedChat.id, history_deleted: params?.isHistoryDeleted || undefined };
|
|
176
|
+
await state.commit(this.#c.messageStorage.storage);
|
|
177
|
+
return constructSecretChat(state.encryptedChat);
|
|
178
|
+
}
|
|
165
179
|
#getNextOutSeqNo(id, isCreator) {
|
|
166
180
|
const state = this.#getSecretChatState(id);
|
|
167
181
|
const rawOutSeqNo = state.outSeqNo;
|
|
@@ -252,23 +266,261 @@ export class SecretChatManager {
|
|
|
252
266
|
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_);
|
|
253
267
|
await this.#postSendMessage(state);
|
|
254
268
|
}
|
|
269
|
+
#generateKeyIv() {
|
|
270
|
+
const key = dntShim.crypto.getRandomValues(new Uint8Array(32));
|
|
271
|
+
const iv = dntShim.crypto.getRandomValues(new Uint8Array(32));
|
|
272
|
+
return [key, iv];
|
|
273
|
+
}
|
|
274
|
+
async sendSecretDocument(id, document, params) {
|
|
275
|
+
this.#c.storage.assertUser("sendSecretDocument");
|
|
276
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
277
|
+
const [key, iv] = this.#generateKeyIv();
|
|
278
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(document, params, null, true, { key, iv });
|
|
279
|
+
const random_id = getRandomId();
|
|
280
|
+
const decryptedMessage = {
|
|
281
|
+
_: "decryptedMessage",
|
|
282
|
+
message: params?.caption ?? "",
|
|
283
|
+
entities: params?.entities?.length ? params.entities.map(secretMessageEntityToTlObject) : undefined,
|
|
284
|
+
random_id,
|
|
285
|
+
ttl: params?.ttl ?? 0,
|
|
286
|
+
silent: params?.isSilent || undefined,
|
|
287
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
288
|
+
via_bot_name: params?.viaBot,
|
|
289
|
+
media: {
|
|
290
|
+
_: "decryptedMessageMediaDocument",
|
|
291
|
+
key,
|
|
292
|
+
iv,
|
|
293
|
+
caption: "",
|
|
294
|
+
size: BigInt(fileSize),
|
|
295
|
+
mime_type: params?.mimeType ?? "",
|
|
296
|
+
attributes: params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : [],
|
|
297
|
+
thumb: new Uint8Array(),
|
|
298
|
+
thumb_w: 0,
|
|
299
|
+
thumb_h: 0,
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
303
|
+
await this.#postSendMessage(state);
|
|
304
|
+
}
|
|
305
|
+
async sendSecretVideo(id, video, params) {
|
|
306
|
+
this.#c.storage.assertUser("sendSecretVideo");
|
|
307
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
308
|
+
const [key, iv] = this.#generateKeyIv();
|
|
309
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(video, params, null, true, { key, iv });
|
|
310
|
+
const random_id = getRandomId();
|
|
311
|
+
const decryptedMessage = {
|
|
312
|
+
_: "decryptedMessage",
|
|
313
|
+
message: params?.caption ?? "",
|
|
314
|
+
entities: params?.entities?.length ? params.entities.map(secretMessageEntityToTlObject) : undefined,
|
|
315
|
+
random_id,
|
|
316
|
+
ttl: params?.ttl ?? 0,
|
|
317
|
+
silent: params?.isSilent || undefined,
|
|
318
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
319
|
+
via_bot_name: params?.viaBot,
|
|
320
|
+
media: {
|
|
321
|
+
_: "decryptedMessageMediaDocument",
|
|
322
|
+
key,
|
|
323
|
+
iv,
|
|
324
|
+
caption: "",
|
|
325
|
+
size: BigInt(fileSize),
|
|
326
|
+
mime_type: params?.mimeType ?? "",
|
|
327
|
+
attributes: [
|
|
328
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
329
|
+
{ _: "documentAttributeVideo", duration: params?.duration ?? 0, w: params?.width ?? 0, h: params?.height ?? 0 },
|
|
330
|
+
],
|
|
331
|
+
thumb: new Uint8Array(),
|
|
332
|
+
thumb_w: 0,
|
|
333
|
+
thumb_h: 0,
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
337
|
+
await this.#postSendMessage(state);
|
|
338
|
+
}
|
|
339
|
+
async sendSecretVideoNote(id, videoNote, params) {
|
|
340
|
+
this.#c.storage.assertUser("sendSecretVideoNote");
|
|
341
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
342
|
+
const [key, iv] = this.#generateKeyIv();
|
|
343
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(videoNote, params, null, true, { key, iv });
|
|
344
|
+
const random_id = getRandomId();
|
|
345
|
+
const decryptedMessage = {
|
|
346
|
+
_: "decryptedMessage",
|
|
347
|
+
message: params?.caption ?? "",
|
|
348
|
+
entities: params?.entities?.length ? params.entities.map(secretMessageEntityToTlObject) : undefined,
|
|
349
|
+
random_id,
|
|
350
|
+
ttl: params?.ttl ?? 0,
|
|
351
|
+
silent: params?.isSilent || undefined,
|
|
352
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
353
|
+
via_bot_name: params?.viaBot,
|
|
354
|
+
media: {
|
|
355
|
+
_: "decryptedMessageMediaDocument",
|
|
356
|
+
key,
|
|
357
|
+
iv,
|
|
358
|
+
caption: "",
|
|
359
|
+
size: BigInt(fileSize),
|
|
360
|
+
mime_type: params?.mimeType ?? "",
|
|
361
|
+
attributes: [
|
|
362
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
363
|
+
{ _: "documentAttributeVideo", duration: params?.duration ?? 0, w: params?.length ?? 0, h: params?.length ?? 0, round_message: true },
|
|
364
|
+
],
|
|
365
|
+
thumb: new Uint8Array(),
|
|
366
|
+
thumb_w: 0,
|
|
367
|
+
thumb_h: 0,
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
371
|
+
await this.#postSendMessage(state);
|
|
372
|
+
}
|
|
373
|
+
async sendSecretAudio(id, audio, params) {
|
|
374
|
+
this.#c.storage.assertUser("sendSecretAudio");
|
|
375
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
376
|
+
const [key, iv] = this.#generateKeyIv();
|
|
377
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(audio, params, null, true, { key, iv });
|
|
378
|
+
const random_id = getRandomId();
|
|
379
|
+
const decryptedMessage = {
|
|
380
|
+
_: "decryptedMessage",
|
|
381
|
+
message: params?.caption ?? "",
|
|
382
|
+
entities: params?.entities?.length ? params.entities.map(secretMessageEntityToTlObject) : undefined,
|
|
383
|
+
random_id,
|
|
384
|
+
ttl: params?.ttl ?? 0,
|
|
385
|
+
silent: params?.isSilent || undefined,
|
|
386
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
387
|
+
via_bot_name: params?.viaBot,
|
|
388
|
+
media: {
|
|
389
|
+
_: "decryptedMessageMediaDocument",
|
|
390
|
+
key,
|
|
391
|
+
iv,
|
|
392
|
+
caption: "",
|
|
393
|
+
size: BigInt(fileSize),
|
|
394
|
+
mime_type: params?.mimeType ?? "",
|
|
395
|
+
attributes: [
|
|
396
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
397
|
+
{ _: "documentAttributeAudio", duration: params?.duration ?? 0, title: params?.title, performer: params?.performer },
|
|
398
|
+
],
|
|
399
|
+
thumb: new Uint8Array(),
|
|
400
|
+
thumb_w: 0,
|
|
401
|
+
thumb_h: 0,
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
405
|
+
await this.#postSendMessage(state);
|
|
406
|
+
}
|
|
407
|
+
async sendSecretVoice(id, voice, params) {
|
|
408
|
+
this.#c.storage.assertUser("sendSecretVoice");
|
|
409
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
410
|
+
const [key, iv] = this.#generateKeyIv();
|
|
411
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(voice, params, null, true, { key, iv });
|
|
412
|
+
const random_id = getRandomId();
|
|
413
|
+
const decryptedMessage = {
|
|
414
|
+
_: "decryptedMessage",
|
|
415
|
+
message: params?.caption ?? "",
|
|
416
|
+
entities: params?.entities?.length ? params.entities.map(secretMessageEntityToTlObject) : undefined,
|
|
417
|
+
random_id,
|
|
418
|
+
ttl: params?.ttl ?? 0,
|
|
419
|
+
silent: params?.isSilent || undefined,
|
|
420
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
421
|
+
via_bot_name: params?.viaBot,
|
|
422
|
+
media: {
|
|
423
|
+
_: "decryptedMessageMediaDocument",
|
|
424
|
+
key,
|
|
425
|
+
iv,
|
|
426
|
+
caption: "",
|
|
427
|
+
size: BigInt(fileSize),
|
|
428
|
+
mime_type: params?.mimeType ?? "",
|
|
429
|
+
attributes: [
|
|
430
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
431
|
+
{ _: "documentAttributeAudio", duration: params?.duration ?? 0, voice: true },
|
|
432
|
+
],
|
|
433
|
+
thumb: new Uint8Array(),
|
|
434
|
+
thumb_w: 0,
|
|
435
|
+
thumb_h: 0,
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
439
|
+
await this.#postSendMessage(state);
|
|
440
|
+
}
|
|
441
|
+
async sendSecretAnimation(id, animation, params) {
|
|
442
|
+
this.#c.storage.assertUser("sendSecretAnimation");
|
|
443
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
444
|
+
const [key, iv] = this.#generateKeyIv();
|
|
445
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(animation, params, null, true, { key, iv });
|
|
446
|
+
const random_id = getRandomId();
|
|
447
|
+
const decryptedMessage = {
|
|
448
|
+
_: "decryptedMessage",
|
|
449
|
+
message: params?.caption ?? "",
|
|
450
|
+
entities: params?.entities?.length ? params.entities.map(secretMessageEntityToTlObject) : undefined,
|
|
451
|
+
random_id,
|
|
452
|
+
ttl: params?.ttl ?? 0,
|
|
453
|
+
silent: params?.isSilent || undefined,
|
|
454
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
455
|
+
via_bot_name: params?.viaBot,
|
|
456
|
+
media: {
|
|
457
|
+
_: "decryptedMessageMediaDocument",
|
|
458
|
+
key,
|
|
459
|
+
iv,
|
|
460
|
+
caption: "",
|
|
461
|
+
size: BigInt(fileSize),
|
|
462
|
+
mime_type: params?.mimeType ?? "",
|
|
463
|
+
attributes: [
|
|
464
|
+
...(params?.fileName ? [{ _: "documentAttributeFilename", file_name: params.fileName }] : []),
|
|
465
|
+
{ _: "documentAttributeVideo", duration: params?.duration ?? 0, w: params?.width ?? 0, h: params?.height ?? 0 },
|
|
466
|
+
{ _: "documentAttributeAnimated" },
|
|
467
|
+
],
|
|
468
|
+
thumb: new Uint8Array(),
|
|
469
|
+
thumb_w: 0,
|
|
470
|
+
thumb_h: 0,
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
474
|
+
await this.#postSendMessage(state);
|
|
475
|
+
}
|
|
476
|
+
async sendSecretPhoto(id, photo, params) {
|
|
477
|
+
this.#c.storage.assertUser("sendSecretPhoto");
|
|
478
|
+
const state = this.#mustGetEncryptedChat(id);
|
|
479
|
+
const [key, iv] = this.#generateKeyIv();
|
|
480
|
+
const { inputEncryptedFile, fileSize } = await this.#c.fileManager.upload(photo, params, checkPhotoName(params), true, { key, iv });
|
|
481
|
+
const random_id = getRandomId();
|
|
482
|
+
const decryptedMessage = {
|
|
483
|
+
_: "decryptedMessage",
|
|
484
|
+
message: params?.caption ?? "",
|
|
485
|
+
entities: params?.entities?.length ? params.entities.map(secretMessageEntityToTlObject) : undefined,
|
|
486
|
+
random_id,
|
|
487
|
+
ttl: params?.ttl ?? 0,
|
|
488
|
+
silent: params?.isSilent || undefined,
|
|
489
|
+
reply_to_random_id: params?.replyToMessageId ? BigInt(params.replyToMessageId) : undefined,
|
|
490
|
+
via_bot_name: params?.viaBot,
|
|
491
|
+
media: {
|
|
492
|
+
_: "decryptedMessageMediaPhoto",
|
|
493
|
+
key,
|
|
494
|
+
iv,
|
|
495
|
+
caption: "",
|
|
496
|
+
size: fileSize,
|
|
497
|
+
w: params?.width ?? 0,
|
|
498
|
+
h: params?.height ?? 0,
|
|
499
|
+
thumb: new Uint8Array(),
|
|
500
|
+
thumb_w: 0,
|
|
501
|
+
thumb_h: 0,
|
|
502
|
+
},
|
|
503
|
+
};
|
|
504
|
+
await this.#sendMessage(decryptedMessage, state.encryptedChat, state.authKey, state.authKeyId_, inputEncryptedFile);
|
|
505
|
+
await this.#postSendMessage(state);
|
|
506
|
+
}
|
|
255
507
|
#sendTails = new Map();
|
|
256
|
-
async #sendMessage(message, encryptedChat, authKey, authKeyId) {
|
|
508
|
+
async #sendMessage(message, encryptedChat, authKey, authKeyId, file) {
|
|
257
509
|
try {
|
|
258
|
-
await this.#sendMessageInner(message, encryptedChat, authKey, authKeyId);
|
|
510
|
+
await this.#sendMessageInner(message, encryptedChat, authKey, authKeyId, file);
|
|
259
511
|
}
|
|
260
512
|
finally {
|
|
261
513
|
await this.#getSecretChatState(encryptedChat.id).commit(this.#c.messageStorage.storage);
|
|
262
514
|
}
|
|
263
515
|
}
|
|
264
|
-
async #sendMessageInner(message, encryptedChat, authKey, authKeyId) {
|
|
516
|
+
async #sendMessageInner(message, encryptedChat, authKey, authKeyId, file) {
|
|
265
517
|
const previous = this.#sendTails.get(encryptedChat.id) ?? Promise.resolve();
|
|
266
518
|
const { promise, resolve } = Promise.withResolvers();
|
|
267
519
|
const tail = previous.then(() => promise);
|
|
268
520
|
this.#sendTails.set(encryptedChat.id, tail);
|
|
269
521
|
await previous;
|
|
270
522
|
try {
|
|
271
|
-
await this.#sendMessageUnlocked(message, encryptedChat, authKey, authKeyId);
|
|
523
|
+
await this.#sendMessageUnlocked(message, encryptedChat, authKey, authKeyId, file);
|
|
272
524
|
}
|
|
273
525
|
finally {
|
|
274
526
|
resolve();
|
|
@@ -277,7 +529,7 @@ export class SecretChatManager {
|
|
|
277
529
|
}
|
|
278
530
|
}
|
|
279
531
|
}
|
|
280
|
-
async #sendMessageUnlocked(message, encryptedChat, authKey, authKeyId) {
|
|
532
|
+
async #sendMessageUnlocked(message, encryptedChat, authKey, authKeyId, file) {
|
|
281
533
|
const random_id = getRandomId();
|
|
282
534
|
const isCreator = Number(encryptedChat.admin_id) === await this.#c.getSelfId();
|
|
283
535
|
const out_seq_no = this.#getNextOutSeqNo(encryptedChat.id, isCreator);
|
|
@@ -285,7 +537,23 @@ export class SecretChatManager {
|
|
|
285
537
|
const decryptedMessageLayer = { _: "decryptedMessageLayer", in_seq_no, layer: 144, message, out_seq_no, random_bytes: dntShim.crypto.getRandomValues(new Uint8Array(15)) };
|
|
286
538
|
const data = await this.#encryptMessage(isCreator, authKeyId, authKey, decryptedMessageLayer);
|
|
287
539
|
this.#getSecretChatState(encryptedChat.id).outgoingMessages.set((out_seq_no - (isCreator ? 1 : 0)) / 2, data);
|
|
288
|
-
|
|
540
|
+
if (file) {
|
|
541
|
+
await this.#c.invoke({
|
|
542
|
+
_: "messages.sendEncryptedFile",
|
|
543
|
+
peer: { _: "inputEncryptedChat", chat_id: encryptedChat.id, access_hash: encryptedChat.access_hash },
|
|
544
|
+
random_id,
|
|
545
|
+
data,
|
|
546
|
+
file,
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
await this.#c.invoke({
|
|
551
|
+
_: "messages.sendEncrypted",
|
|
552
|
+
peer: { _: "inputEncryptedChat", chat_id: encryptedChat.id, access_hash: encryptedChat.access_hash },
|
|
553
|
+
random_id,
|
|
554
|
+
data,
|
|
555
|
+
});
|
|
556
|
+
}
|
|
289
557
|
const state = this.#getSecretChatState(encryptedChat.id);
|
|
290
558
|
if (equals(state.authKeyId_, authKeyId)) {
|
|
291
559
|
++state.authKeyUseCount;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import { type Api } from "../2_tl.js";
|
|
21
21
|
import type { AvailableReactions, BusinessConnection, CallbackQuery, Chat, ChatActionType, ChatMember, ChatP, ChatPChannel, ChatPGroup, ChatPPrivate, ChatPSupergroup, ChatSettings, ChosenInlineResult, ClaimedGifts, FailedInvitation, FileSource, GuestQuery, ID, InlineQuery, InlineQueryResult, InputChecklistItem, InputMedia, InputPollOption, InputRichText, InputStoryContent, InviteLink, JoinRequest, Message, MessageAnimation, MessageAudio, MessageChecklist, MessageContact, MessageDice, MessageDocument, MessageInvoice, MessageList, MessageLocation, MessagePhoto, MessagePoll, MessageReactionList, MessageRichText, MessageSticker, MessageText, MessageVenue, MessageVideo, MessageVideoNote, MessageVoice, Poll, PriceTag, Reaction, RichText, SecretChat, SecretMessage, SlowModeDuration, Story, Topic, Update, User, VideoChatActive, VideoChatScheduled, VoiceTranscription } from "../3_types.js";
|
|
22
|
-
import type { AddChatMemberParams, AddContactParams, AddReactionParams, AnswerCallbackQueryParams, AnswerInlineQueryParams, AnswerPreCheckoutQueryParams, ApproveJoinRequestsParams, BanChatMemberParams, CreateInviteLinkParams, CreateStoryParams, CreateTopicParams, DeclineJoinRequestsParams, DeleteMessagesParams, EditInlineMessageCaptionParams, EditInlineMessageMediaParams, EditInlineMessageRichTextParams, EditInlineMessageTextParams, EditMessageCaptionParams, EditMessageLiveLocationParams, EditMessageMediaParams, EditMessageReplyMarkupParams, EditMessageRichTextParams, EditMessageTextParams, EditTopicParams, EnableSignaturesParams, ForwardMessagesParams, GetChatMembersParams, GetClaimedGiftsParams, GetCreatedInviteLinksParams, GetHistoryParams, GetJoinRequestsParams, GetSavedMessagesParams, PinMessageParams, PromoteChatMemberParams, ReplyParams, ScheduleVideoChatParams, SearchMessagesParams, SendAnimationParams, SendAudioParams, SendChecklistParams, SendContactParams, SendDiceParams, SendDocumentParams, SendGiftParams, SendInvoiceParams, SendLocationParams, SendMediaGroupParams, SendMessageDraftParams, SendMessageParams, SendPhotoParams, SendPollParams, SendRichTextDraftParams, SendSecretContactParams, SendSecretLocationParams, SendSecretMessageParams, SendSecretVenueParams, SendStickerParams, SendVenueParams, SendVideoNoteParams, SendVideoParams, SendVoiceParams, SetChatMemberRightsParams, SetChatMemberTagParams, SetChatPhotoParams, SetReactionsParams, StartVideoChatParams, StopPollParams, UpdateChecklistParams } from "./0_params.js";
|
|
22
|
+
import type { AddChatMemberParams, AddContactParams, AddReactionParams, AnswerCallbackQueryParams, AnswerInlineQueryParams, AnswerPreCheckoutQueryParams, ApproveJoinRequestsParams, BanChatMemberParams, CreateInviteLinkParams, CreateStoryParams, CreateTopicParams, DeclineJoinRequestsParams, DeleteMessagesParams, EditInlineMessageCaptionParams, EditInlineMessageMediaParams, EditInlineMessageRichTextParams, EditInlineMessageTextParams, EditMessageCaptionParams, EditMessageLiveLocationParams, EditMessageMediaParams, EditMessageReplyMarkupParams, EditMessageRichTextParams, EditMessageTextParams, EditTopicParams, EnableSignaturesParams, EndSecretChatParams, ForwardMessagesParams, GetChatMembersParams, GetClaimedGiftsParams, GetCreatedInviteLinksParams, GetHistoryParams, GetJoinRequestsParams, GetSavedMessagesParams, PinMessageParams, PromoteChatMemberParams, ReplyParams, ScheduleVideoChatParams, SearchMessagesParams, SendAnimationParams, SendAudioParams, SendChecklistParams, SendContactParams, SendDiceParams, SendDocumentParams, SendGiftParams, SendInvoiceParams, SendLocationParams, SendMediaGroupParams, SendMessageDraftParams, SendMessageParams, SendPhotoParams, SendPollParams, SendRichTextDraftParams, SendSecretContactParams, SendSecretLocationParams, SendSecretMessageParams, SendSecretVenueParams, SendStickerParams, SendVenueParams, SendVideoNoteParams, SendVideoParams, SendVoiceParams, SetChatMemberRightsParams, SetChatMemberTagParams, SetChatPhotoParams, SetReactionsParams, StartVideoChatParams, StopPollParams, UpdateChecklistParams } from "./0_params.js";
|
|
23
23
|
import type { ClientGeneric } from "./1_client_generic.js";
|
|
24
24
|
import { type FilterQuery, type WithChatType, type WithFilter } from "./3_filters.js";
|
|
25
25
|
export type ContextCommands = string | RegExp | (string | RegExp)[] | {
|
|
@@ -299,6 +299,8 @@ export declare class Context {
|
|
|
299
299
|
replySecretContact(firstName: string, phoneNumber: string, params?: Omit<SendSecretContactParams, "replyToMessaegId"> & ReplyParams): Promise<void>;
|
|
300
300
|
/** Context-aware alias for {@link Client.acceptSecretChat}. */
|
|
301
301
|
acceptSecretChat(): Promise<SecretChat>;
|
|
302
|
+
/** Context-aware alias for {@link Client.acceptSecretChat}. */
|
|
303
|
+
endSecretChat(params?: EndSecretChatParams): Promise<SecretChat>;
|
|
302
304
|
/** Context-aware alias for {@link Client.requestSecretChat}. */
|
|
303
305
|
requestSecretChat(): Promise<SecretChat>;
|
|
304
306
|
/** Context-aware alias for {@link Client.sendMessage}. */
|