@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.
Files changed (107) hide show
  1. package/esm/0_deps.d.ts +1 -0
  2. package/esm/0_deps.d.ts.map +1 -1
  3. package/esm/0_deps.js +1 -0
  4. package/esm/client/0_params.d.ts +52 -0
  5. package/esm/client/0_params.d.ts.map +1 -1
  6. package/esm/client/1_client_generic.d.ts +64 -1
  7. package/esm/client/1_client_generic.d.ts.map +1 -1
  8. package/esm/client/2_file_manager.d.ts +9 -1
  9. package/esm/client/2_file_manager.d.ts.map +1 -1
  10. package/esm/client/2_file_manager.js +77 -27
  11. package/esm/client/3_secret_chat_manager.d.ts +10 -2
  12. package/esm/client/3_secret_chat_manager.d.ts.map +1 -1
  13. package/esm/client/3_secret_chat_manager.js +274 -6
  14. package/esm/client/4_context.d.ts +3 -1
  15. package/esm/client/4_context.d.ts.map +1 -1
  16. package/esm/client/4_context.js +5 -0
  17. package/esm/client/6_client.d.ts +64 -1
  18. package/esm/client/6_client.d.ts.map +1 -1
  19. package/esm/client/6_client.js +79 -0
  20. package/esm/client/6_client_dispatcher.d.ts +64 -1
  21. package/esm/client/6_client_dispatcher.d.ts.map +1 -1
  22. package/esm/client/6_client_dispatcher.js +79 -0
  23. package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts +9 -0
  24. package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts.map +1 -0
  25. package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.js +2 -0
  26. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts +2 -0
  27. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts.map +1 -0
  28. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts +69 -0
  29. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts.map +1 -0
  30. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.js +237 -0
  31. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.js +2277 -0
  32. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts +13 -0
  33. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts.map +1 -0
  34. package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.js +46 -0
  35. package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts +76 -0
  36. package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts.map +1 -0
  37. package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.js +132 -0
  38. package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts +149 -0
  39. package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts.map +1 -0
  40. package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.js +270 -0
  41. package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts +22 -0
  42. package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts.map +1 -0
  43. package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.js +23 -0
  44. package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +40 -0
  45. package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts.map +1 -0
  46. package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +61 -0
  47. package/esm/tl/0_utilities.d.ts.map +1 -1
  48. package/esm/tl/0_utilities.js +44 -2
  49. package/esm/tl/1_tl_writer.d.ts.map +1 -1
  50. package/esm/tl/1_tl_writer.js +6 -1
  51. package/esm/types/1_sticker.d.ts +7 -9
  52. package/esm/types/1_sticker.d.ts.map +1 -1
  53. package/esm/types/1_sticker.js +1 -6
  54. package/package.json +1 -1
  55. package/script/0_deps.d.ts +1 -0
  56. package/script/0_deps.d.ts.map +1 -1
  57. package/script/0_deps.js +7 -5
  58. package/script/client/0_params.d.ts +52 -0
  59. package/script/client/0_params.d.ts.map +1 -1
  60. package/script/client/1_client_generic.d.ts +64 -1
  61. package/script/client/1_client_generic.d.ts.map +1 -1
  62. package/script/client/2_file_manager.d.ts +9 -1
  63. package/script/client/2_file_manager.d.ts.map +1 -1
  64. package/script/client/2_file_manager.js +74 -24
  65. package/script/client/3_secret_chat_manager.d.ts +10 -2
  66. package/script/client/3_secret_chat_manager.d.ts.map +1 -1
  67. package/script/client/3_secret_chat_manager.js +274 -6
  68. package/script/client/4_context.d.ts +3 -1
  69. package/script/client/4_context.d.ts.map +1 -1
  70. package/script/client/4_context.js +5 -0
  71. package/script/client/6_client.d.ts +64 -1
  72. package/script/client/6_client.d.ts.map +1 -1
  73. package/script/client/6_client.js +79 -0
  74. package/script/client/6_client_dispatcher.d.ts +64 -1
  75. package/script/client/6_client_dispatcher.d.ts.map +1 -1
  76. package/script/client/6_client_dispatcher.js +79 -0
  77. package/script/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts +9 -0
  78. package/script/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts.map +1 -0
  79. package/script/deps/jsr.io/@std/crypto/1.1.0/_types.js +3 -0
  80. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts +2 -0
  81. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts.map +1 -0
  82. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts +69 -0
  83. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts.map +1 -0
  84. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.js +255 -0
  85. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.js +2315 -0
  86. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts +13 -0
  87. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts.map +1 -0
  88. package/script/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.js +51 -0
  89. package/script/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts +76 -0
  90. package/script/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts.map +1 -0
  91. package/script/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.js +169 -0
  92. package/script/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts +149 -0
  93. package/script/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts.map +1 -0
  94. package/script/deps/jsr.io/@std/crypto/1.1.0/crypto.js +306 -0
  95. package/script/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts +22 -0
  96. package/script/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts.map +1 -0
  97. package/script/deps/jsr.io/@std/crypto/1.1.0/mod.js +39 -0
  98. package/script/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +40 -0
  99. package/script/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts.map +1 -0
  100. package/script/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +64 -0
  101. package/script/tl/0_utilities.d.ts.map +1 -1
  102. package/script/tl/0_utilities.js +43 -1
  103. package/script/tl/1_tl_writer.d.ts.map +1 -1
  104. package/script/tl/1_tl_writer.js +6 -1
  105. package/script/types/1_sticker.d.ts +7 -9
  106. package/script/types/1_sticker.d.ts.map +1 -1
  107. 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
- const bytes = buffer.subarray(start, end);
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
- let ms = 0.05;
403
+ const requestCount = DOWNLOAD_POOL_SIZE * DOWNLOAD_REQUEST_PER_CONNECTION;
404
+ let finished = false;
367
405
  while (true) {
368
406
  signal?.throwIfAborted();
369
- let retryIn = 1;
370
- let errorCount = 0;
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", file)) {
375
- const downloadedSize = file.bytes.byteLength;
376
- let finished = downloadedSize < limit;
410
+ if (Api.is("upload.file", result)) {
411
+ const downloadedSize = result.bytes.byteLength;
412
+ finished = downloadedSize < limit;
377
413
  if (decryptionInformation) {
378
- const decryptedBytes = ige256Decrypt(file.bytes, decryptionInformation.key, decryptionInformation.iv);
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
- file.bytes = decryptedBytes.slice(0, remainingSize);
381
- totalSize += file.bytes.byteLength;
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 file.bytes;
423
+ yield result.bytes;
385
424
  if (id !== null) {
386
- await this.#c.storage.saveFilePart(id, part, file.bytes);
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
- await delay(ms);
405
- ms = Math.max(ms * .8, 0.003);
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 = 0;
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;AAGpF,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGvI,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/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;IA0E3B,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;IAie5G,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"}
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
- await this.#c.invoke({ _: "messages.sendEncrypted", peer: { _: "inputEncryptedChat", chat_id: encryptedChat.id, access_hash: encryptedChat.access_hash }, random_id, data });
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}. */