@mtcute/core 0.1.0 → 0.1.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.
Files changed (219) hide show
  1. package/cjs/base-client.js +4 -1
  2. package/cjs/base-client.js.map +1 -1
  3. package/cjs/network/auth-key.d.ts +3 -3
  4. package/cjs/network/auth-key.js +12 -12
  5. package/cjs/network/auth-key.js.map +1 -1
  6. package/cjs/network/authorization.js +62 -57
  7. package/cjs/network/authorization.js.map +1 -1
  8. package/cjs/network/mtproto-session.d.ts +2 -2
  9. package/cjs/network/mtproto-session.js +2 -2
  10. package/cjs/network/mtproto-session.js.map +1 -1
  11. package/cjs/network/multi-session-connection.d.ts +1 -1
  12. package/cjs/network/multi-session-connection.js +2 -2
  13. package/cjs/network/multi-session-connection.js.map +1 -1
  14. package/cjs/network/network-manager.d.ts +1 -0
  15. package/cjs/network/network-manager.js +21 -27
  16. package/cjs/network/network-manager.js.map +1 -1
  17. package/cjs/network/session-connection.d.ts +2 -1
  18. package/cjs/network/session-connection.js +48 -35
  19. package/cjs/network/session-connection.js.map +1 -1
  20. package/cjs/network/transports/intermediate.d.ts +3 -0
  21. package/cjs/network/transports/intermediate.js +5 -3
  22. package/cjs/network/transports/intermediate.js.map +1 -1
  23. package/cjs/network/transports/obfuscated.js +14 -18
  24. package/cjs/network/transports/obfuscated.js.map +1 -1
  25. package/cjs/storage/abstract.d.ts +23 -2
  26. package/cjs/storage/abstract.js.map +1 -1
  27. package/cjs/storage/json.js +8 -9
  28. package/cjs/storage/json.js.map +1 -1
  29. package/cjs/storage/localstorage.js +5 -2
  30. package/cjs/storage/localstorage.js.map +1 -1
  31. package/cjs/storage/memory.d.ts +7 -8
  32. package/cjs/storage/memory.js +7 -7
  33. package/cjs/storage/memory.js.map +1 -1
  34. package/cjs/utils/bigint-utils.d.ts +18 -11
  35. package/cjs/utils/bigint-utils.js +148 -47
  36. package/cjs/utils/bigint-utils.js.map +1 -1
  37. package/cjs/utils/buffer-utils.d.ts +7 -1
  38. package/cjs/utils/buffer-utils.js +16 -3
  39. package/cjs/utils/buffer-utils.js.map +1 -1
  40. package/cjs/utils/crypto/abstract.d.ts +16 -9
  41. package/cjs/utils/crypto/abstract.js +6 -9
  42. package/cjs/utils/crypto/abstract.js.map +1 -1
  43. package/cjs/utils/crypto/factorization.d.ts +2 -1
  44. package/cjs/utils/crypto/factorization.js +28 -36
  45. package/cjs/utils/crypto/factorization.js.map +1 -1
  46. package/cjs/utils/crypto/index.d.ts +4 -0
  47. package/cjs/utils/crypto/index.js +4 -0
  48. package/cjs/utils/crypto/index.js.map +1 -1
  49. package/cjs/utils/crypto/keys.d.ts +2 -2
  50. package/cjs/utils/crypto/keys.js +4 -4
  51. package/cjs/utils/crypto/keys.js.map +1 -1
  52. package/cjs/utils/crypto/miller-rabin.d.ts +2 -2
  53. package/cjs/utils/crypto/miller-rabin.js +20 -22
  54. package/cjs/utils/crypto/miller-rabin.js.map +1 -1
  55. package/cjs/utils/crypto/mtproto.d.ts +3 -3
  56. package/cjs/utils/crypto/mtproto.js +12 -12
  57. package/cjs/utils/crypto/mtproto.js.map +1 -1
  58. package/cjs/utils/crypto/node.d.ts +21 -0
  59. package/cjs/utils/crypto/node.js +74 -0
  60. package/cjs/utils/crypto/node.js.map +1 -0
  61. package/cjs/utils/crypto/password.js +22 -33
  62. package/cjs/utils/crypto/password.js.map +1 -1
  63. package/cjs/utils/crypto/wasm.d.ts +22 -0
  64. package/cjs/utils/crypto/wasm.js +41 -0
  65. package/cjs/utils/crypto/wasm.js.map +1 -0
  66. package/cjs/utils/crypto/web.d.ts +11 -0
  67. package/cjs/utils/crypto/web.js +40 -0
  68. package/cjs/utils/crypto/web.js.map +1 -0
  69. package/cjs/utils/deque.d.ts +1 -1
  70. package/cjs/utils/deque.js +9 -3
  71. package/cjs/utils/deque.js.map +1 -1
  72. package/cjs/utils/function-utils.d.ts +4 -1
  73. package/cjs/utils/function-utils.js +8 -1
  74. package/cjs/utils/function-utils.js.map +1 -1
  75. package/cjs/utils/index.d.ts +0 -1
  76. package/cjs/utils/index.js +0 -1
  77. package/cjs/utils/index.js.map +1 -1
  78. package/cjs/utils/logger.d.ts +0 -1
  79. package/cjs/utils/logger.js +3 -4
  80. package/cjs/utils/logger.js.map +1 -1
  81. package/cjs/utils/lru-map.d.ts +1 -0
  82. package/cjs/utils/lru-map.js +6 -0
  83. package/cjs/utils/lru-map.js.map +1 -1
  84. package/cjs/utils/peer-utils.js +5 -1
  85. package/cjs/utils/peer-utils.js.map +1 -1
  86. package/cjs/utils/platform/crypto.js +2 -2
  87. package/cjs/utils/platform/crypto.js.map +1 -1
  88. package/cjs/utils/platform/crypto.web.js +2 -2
  89. package/cjs/utils/platform/crypto.web.js.map +1 -1
  90. package/cjs/utils/string-session.js +4 -2
  91. package/cjs/utils/string-session.js.map +1 -1
  92. package/esm/base-client.js +4 -1
  93. package/esm/base-client.js.map +1 -1
  94. package/esm/network/auth-key.d.ts +3 -3
  95. package/esm/network/auth-key.js +13 -13
  96. package/esm/network/auth-key.js.map +1 -1
  97. package/esm/network/authorization.js +64 -59
  98. package/esm/network/authorization.js.map +1 -1
  99. package/esm/network/mtproto-session.d.ts +2 -2
  100. package/esm/network/mtproto-session.js +2 -2
  101. package/esm/network/mtproto-session.js.map +1 -1
  102. package/esm/network/multi-session-connection.d.ts +1 -1
  103. package/esm/network/multi-session-connection.js +2 -2
  104. package/esm/network/multi-session-connection.js.map +1 -1
  105. package/esm/network/network-manager.d.ts +1 -0
  106. package/esm/network/network-manager.js +21 -27
  107. package/esm/network/network-manager.js.map +1 -1
  108. package/esm/network/session-connection.d.ts +2 -1
  109. package/esm/network/session-connection.js +50 -37
  110. package/esm/network/session-connection.js.map +1 -1
  111. package/esm/network/transports/intermediate.d.ts +3 -0
  112. package/esm/network/transports/intermediate.js +6 -4
  113. package/esm/network/transports/intermediate.js.map +1 -1
  114. package/esm/network/transports/obfuscated.js +15 -19
  115. package/esm/network/transports/obfuscated.js.map +1 -1
  116. package/esm/storage/abstract.d.ts +23 -2
  117. package/esm/storage/abstract.js.map +1 -1
  118. package/esm/storage/json.js +8 -9
  119. package/esm/storage/json.js.map +1 -1
  120. package/esm/storage/localstorage.js +5 -2
  121. package/esm/storage/localstorage.js.map +1 -1
  122. package/esm/storage/memory.d.ts +7 -8
  123. package/esm/storage/memory.js +7 -7
  124. package/esm/storage/memory.js.map +1 -1
  125. package/esm/utils/bigint-utils.d.ts +18 -11
  126. package/esm/utils/bigint-utils.js +142 -44
  127. package/esm/utils/bigint-utils.js.map +1 -1
  128. package/esm/utils/buffer-utils.d.ts +7 -1
  129. package/esm/utils/buffer-utils.js +14 -1
  130. package/esm/utils/buffer-utils.js.map +1 -1
  131. package/esm/utils/crypto/abstract.d.ts +16 -9
  132. package/esm/utils/crypto/abstract.js +6 -9
  133. package/esm/utils/crypto/abstract.js.map +1 -1
  134. package/esm/utils/crypto/factorization.d.ts +2 -1
  135. package/esm/utils/crypto/factorization.js +29 -34
  136. package/esm/utils/crypto/factorization.js.map +1 -1
  137. package/esm/utils/crypto/index.d.ts +4 -0
  138. package/esm/utils/crypto/index.js +4 -0
  139. package/esm/utils/crypto/index.js.map +1 -1
  140. package/esm/utils/crypto/keys.d.ts +2 -2
  141. package/esm/utils/crypto/keys.js +4 -4
  142. package/esm/utils/crypto/keys.js.map +1 -1
  143. package/esm/utils/crypto/miller-rabin.d.ts +2 -2
  144. package/esm/utils/crypto/miller-rabin.js +21 -20
  145. package/esm/utils/crypto/miller-rabin.js.map +1 -1
  146. package/esm/utils/crypto/mtproto.d.ts +3 -3
  147. package/esm/utils/crypto/mtproto.js +12 -12
  148. package/esm/utils/crypto/mtproto.js.map +1 -1
  149. package/esm/utils/crypto/node.d.ts +21 -0
  150. package/esm/utils/crypto/node.js +69 -0
  151. package/esm/utils/crypto/node.js.map +1 -0
  152. package/esm/utils/crypto/password.js +24 -32
  153. package/esm/utils/crypto/password.js.map +1 -1
  154. package/esm/utils/crypto/wasm.d.ts +22 -0
  155. package/esm/utils/crypto/wasm.js +37 -0
  156. package/esm/utils/crypto/wasm.js.map +1 -0
  157. package/esm/utils/crypto/web.d.ts +11 -0
  158. package/esm/utils/crypto/web.js +36 -0
  159. package/esm/utils/crypto/web.js.map +1 -0
  160. package/esm/utils/deque.d.ts +1 -1
  161. package/esm/utils/deque.js +9 -3
  162. package/esm/utils/deque.js.map +1 -1
  163. package/esm/utils/function-utils.d.ts +4 -1
  164. package/esm/utils/function-utils.js +8 -1
  165. package/esm/utils/function-utils.js.map +1 -1
  166. package/esm/utils/index.d.ts +0 -1
  167. package/esm/utils/index.js +0 -1
  168. package/esm/utils/index.js.map +1 -1
  169. package/esm/utils/logger.d.ts +0 -1
  170. package/esm/utils/logger.js +3 -4
  171. package/esm/utils/logger.js.map +1 -1
  172. package/esm/utils/lru-map.d.ts +1 -0
  173. package/esm/utils/lru-map.js +6 -0
  174. package/esm/utils/lru-map.js.map +1 -1
  175. package/esm/utils/peer-utils.js +5 -1
  176. package/esm/utils/peer-utils.js.map +1 -1
  177. package/esm/utils/platform/crypto.js +1 -1
  178. package/esm/utils/platform/crypto.js.map +1 -1
  179. package/esm/utils/platform/crypto.web.js +2 -2
  180. package/esm/utils/platform/crypto.web.js.map +1 -1
  181. package/esm/utils/string-session.js +4 -2
  182. package/esm/utils/string-session.js.map +1 -1
  183. package/package.json +4 -5
  184. package/cjs/utils/crypto/common.d.ts +0 -12
  185. package/cjs/utils/crypto/common.js +0 -54
  186. package/cjs/utils/crypto/common.js.map +0 -1
  187. package/cjs/utils/crypto/node-crypto.d.ts +0 -10
  188. package/cjs/utils/crypto/node-crypto.js +0 -46
  189. package/cjs/utils/crypto/node-crypto.js.map +0 -1
  190. package/cjs/utils/crypto/subtle.d.ts +0 -12
  191. package/cjs/utils/crypto/subtle.js +0 -86
  192. package/cjs/utils/crypto/subtle.js.map +0 -1
  193. package/cjs/utils/flood-control.d.ts +0 -14
  194. package/cjs/utils/flood-control.js +0 -65
  195. package/cjs/utils/flood-control.js.map +0 -1
  196. package/cjs/utils/platform/random.d.ts +0 -1
  197. package/cjs/utils/platform/random.js +0 -7
  198. package/cjs/utils/platform/random.js.map +0 -1
  199. package/cjs/utils/platform/random.web.d.ts +0 -1
  200. package/cjs/utils/platform/random.web.js +0 -10
  201. package/cjs/utils/platform/random.web.js.map +0 -1
  202. package/esm/utils/crypto/common.d.ts +0 -12
  203. package/esm/utils/crypto/common.js +0 -50
  204. package/esm/utils/crypto/common.js.map +0 -1
  205. package/esm/utils/crypto/node-crypto.d.ts +0 -10
  206. package/esm/utils/crypto/node-crypto.js +0 -42
  207. package/esm/utils/crypto/node-crypto.js.map +0 -1
  208. package/esm/utils/crypto/subtle.d.ts +0 -12
  209. package/esm/utils/crypto/subtle.js +0 -59
  210. package/esm/utils/crypto/subtle.js.map +0 -1
  211. package/esm/utils/flood-control.d.ts +0 -14
  212. package/esm/utils/flood-control.js +0 -61
  213. package/esm/utils/flood-control.js.map +0 -1
  214. package/esm/utils/platform/random.d.ts +0 -1
  215. package/esm/utils/platform/random.js +0 -4
  216. package/esm/utils/platform/random.js.map +0 -1
  217. package/esm/utils/platform/random.web.d.ts +0 -1
  218. package/esm/utils/platform/random.web.js +0 -6
  219. package/esm/utils/platform/random.web.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"base-client.js","sourceRoot":"","sources":["../../src/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport EventEmitter from 'events'\nimport Long from 'long'\n\nimport { tl } from '@mtcute/tl'\nimport { __tlReaderMap as defaultReaderMap } from '@mtcute/tl/binary/reader.js'\nimport { __tlWriterMap as defaultWriterMap } from '@mtcute/tl/binary/writer.js'\nimport { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'\n\nimport { ConfigManager } from './network/config-manager.js'\nimport { ReconnectionStrategy, SessionConnection, TransportFactory } from './network/index.js'\nimport { NetworkManager, NetworkManagerExtraParams, RpcCallOptions } from './network/network-manager.js'\nimport { PersistentConnectionParams } from './network/persistent-connection.js'\nimport { ITelegramStorage, MemoryStorage } from './storage/index.js'\nimport { MustEqual } from './types/index.js'\nimport {\n ControllablePromise,\n createControllablePromise,\n CryptoProviderFactory,\n defaultCryptoProviderFactory,\n defaultProductionDc,\n defaultProductionIpv6Dc,\n defaultTestDc,\n defaultTestIpv6Dc,\n getAllPeersFrom,\n ICryptoProvider,\n LogManager,\n readStringSession,\n toggleChannelIdMark,\n writeStringSession,\n} from './utils/index.js'\n\n/** Options for {@link BaseTelegramClient} */\nexport interface BaseTelegramClientOptions {\n /**\n * API ID from my.telegram.org\n */\n apiId: number | string\n /**\n * API hash from my.telegram.org\n */\n apiHash: string\n\n /**\n * Telegram storage to use.\n * If omitted, {@link MemoryStorage} is used\n */\n storage?: ITelegramStorage\n\n /**\n * Cryptography provider factory to allow delegating\n * crypto to native addon, worker, etc.\n */\n crypto?: CryptoProviderFactory\n\n /**\n * Whether to use IPv6 datacenters\n * (IPv6 will be preferred when choosing a DC by id)\n * (default: false)\n */\n useIpv6?: boolean\n\n /**\n * Primary DC to use for initial connection.\n * This does not mean this will be the only DC used,\n * nor that this DC will actually be primary, this only\n * determines the first DC the library will try to connect to.\n * Can be used to connect to other networks (like test DCs).\n *\n * When session already contains primary DC, this parameter is ignored.\n *\n * @default Production DC 2.\n */\n defaultDcs?: ITelegramStorage.DcOptions\n\n /**\n * Whether to connect to test servers.\n *\n * If passed, {@link defaultDc} defaults to Test DC 2.\n *\n * **Must** be passed if using test servers, even if\n * you passed custom {@link defaultDc}\n */\n testMode?: boolean\n\n /**\n * Additional options for initConnection call.\n * `apiId` and `query` are not available and will be ignored.\n * Omitted values will be filled with defaults\n */\n initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>\n\n /**\n * Transport factory to use in the client.\n *\n * @default platform-specific transport: WebSocket on the web, TCP in node\n */\n transport?: TransportFactory\n\n /**\n * Reconnection strategy.\n *\n * @default simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)\n */\n reconnectionStrategy?: ReconnectionStrategy<PersistentConnectionParams>\n\n /**\n * Maximum duration of a flood_wait that will be waited automatically.\n * Flood waits above this threshold will throw a FloodWaitError.\n * Set to 0 to disable. Can be overridden with `throwFlood` parameter in call() params\n *\n * @default 10000\n */\n floodSleepThreshold?: number\n\n /**\n * Maximum number of retries when calling RPC methods.\n * Call is retried when InternalError or FloodWaitError is encountered.\n * Can be set to Infinity.\n *\n * @default 5\n */\n maxRetryCount?: number\n\n /**\n * If true, every single API call will be wrapped with `tl.invokeWithoutUpdates`,\n * effectively disabling the server-sent events for the clients.\n * May be useful in some cases.\n *\n * Note that this only wraps calls made with `.call()` within the primary\n * connection. Additional connections and direct `.sendForResult()` calls\n * must be wrapped manually.\n *\n * @default false\n */\n disableUpdates?: boolean\n\n /**\n * mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s\n * [error reporting service](https://rpc.pwrtelegram.xyz/).\n *\n * This is fully anonymous (except maybe IP) and is only used to improve the library\n * and developer experience for everyone working with MTProto. This is fully opt-in,\n * and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.\n *\n * @default false\n */\n enableErrorReporting?: boolean\n\n /**\n * If true, RPC errors will have a stack trace of the initial `.call()`\n * or `.sendForResult()` call position, which drastically improves\n * debugging experience.<br>\n * If false, they will have a stack trace of mtcute internals.\n *\n * Internally this creates a stack capture before every RPC call\n * and stores it until the result is received. This might\n * use a lot more memory than normal, thus can be disabled here.\n *\n * @default true\n */\n niceStacks?: boolean\n\n /**\n * Extra parameters for {@link NetworkManager}\n */\n network?: NetworkManagerExtraParams\n\n /**\n * Set logging level for the client.\n *\n * See static members of {@link LogManager} for possible values.\n */\n logLevel?: number\n\n /**\n * **EXPERT USE ONLY!**\n *\n * Override TL layer used for the connection.\n *\n * **Does not** change the schema used.\n */\n overrideLayer?: number\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override reader map used for the connection.\n */\n readerMap?: TlReaderMap\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override writer map used for the connection.\n */\n writerMap?: TlWriterMap\n}\n\n/**\n * Basic Telegram client that only implements the bare minimum\n * to make RPC calls and receive low-level updates.\n */\nexport class BaseTelegramClient extends EventEmitter {\n /**\n * Crypto provider taken from {@link BaseTelegramClientOptions.crypto}\n */\n readonly crypto: ICryptoProvider\n\n /**\n * Telegram storage taken from {@link BaseTelegramClientOptions.storage}\n */\n readonly storage: ITelegramStorage\n\n /**\n * API hash taken from {@link BaseTelegramClientOptions.apiHash}\n */\n protected readonly _apiHash: string\n\n /**\n * \"Use IPv6\" taken from {@link BaseTelegramClientOptions.useIpv6}\n */\n protected readonly _useIpv6: boolean\n\n /**\n * \"Test mode\" taken from {@link BaseTelegramClientOptions.testMode}\n */\n protected readonly _testMode: boolean\n\n /**\n * Primary DCs taken from {@link BaseTelegramClientOptions.defaultDcs},\n * loaded from session or changed by other means (like redirecting).\n */\n protected _defaultDcs: ITelegramStorage.DcOptions\n\n private _niceStacks: boolean\n /** TL layer used by the client */\n readonly _layer: number\n /** TL readers map used by the client */\n readonly _readerMap: TlReaderMap\n /** TL writers map used by the client */\n readonly _writerMap: TlWriterMap\n\n /** Unix timestamp when the last update was received */\n protected _lastUpdateTime = 0\n\n readonly _config = new ConfigManager(() => this.call({ _: 'help.getConfig' }))\n\n // not really connected, but rather \"connect() was called\"\n private _connected: ControllablePromise<void> | boolean = false\n\n private _onError?: (err: unknown, connection?: SessionConnection) => void\n\n private _importFrom?: string\n private _importForce?: boolean\n\n readonly log = new LogManager('client')\n readonly network: NetworkManager\n\n constructor(opts: BaseTelegramClientOptions) {\n super()\n\n const apiId = typeof opts.apiId === 'string' ? parseInt(opts.apiId) : opts.apiId\n\n if (isNaN(apiId)) {\n throw new Error('apiId must be a number or a numeric string!')\n }\n\n if (opts.logLevel) this.log.level = opts.logLevel\n\n this.crypto = (opts.crypto ?? defaultCryptoProviderFactory)()\n this.storage = opts.storage ?? new MemoryStorage()\n this._apiHash = opts.apiHash\n this._useIpv6 = Boolean(opts.useIpv6)\n this._testMode = Boolean(opts.testMode)\n\n let dc = opts.defaultDcs\n\n if (!dc) {\n if (this._testMode) {\n dc = this._useIpv6 ? defaultTestIpv6Dc : defaultTestDc\n } else {\n dc = this._useIpv6 ? defaultProductionIpv6Dc : defaultProductionDc\n }\n }\n\n this._defaultDcs = dc\n this._niceStacks = opts.niceStacks ?? true\n\n this._layer = opts.overrideLayer ?? tl.LAYER\n this._readerMap = opts.readerMap ?? defaultReaderMap\n this._writerMap = opts.writerMap ?? defaultWriterMap\n\n this.network = new NetworkManager(\n {\n apiId,\n crypto: this.crypto,\n disableUpdates: opts.disableUpdates ?? false,\n initConnectionOptions: opts.initConnectionOptions,\n layer: this._layer,\n log: this.log,\n readerMap: this._readerMap,\n writerMap: this._writerMap,\n reconnectionStrategy: opts.reconnectionStrategy,\n storage: this.storage,\n testMode: this._testMode,\n transport: opts.transport,\n _emitError: this._emitError.bind(this),\n floodSleepThreshold: opts.floodSleepThreshold ?? 10000,\n maxRetryCount: opts.maxRetryCount ?? 5,\n isPremium: false,\n useIpv6: Boolean(opts.useIpv6),\n keepAliveAction: this._keepAliveAction.bind(this),\n enableErrorReporting: opts.enableErrorReporting ?? false,\n ...(opts.network ?? {}),\n },\n this._config,\n )\n\n this.storage.setup?.(this.log, this._readerMap, this._writerMap)\n }\n\n protected _keepAliveAction(): void {\n this.emit('keep_alive')\n }\n\n protected async _loadStorage(): Promise<void> {\n await this.storage.load?.()\n }\n\n _beforeStorageSave: (() => Promise<void>)[] = []\n\n beforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave.push(cb)\n }\n\n offBeforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave = this._beforeStorageSave.filter((x) => x !== cb)\n }\n\n async saveStorage(): Promise<void> {\n for (const cb of this._beforeStorageSave) {\n await cb()\n }\n await this.storage.save?.()\n }\n\n /**\n * Initialize the connection to the primary DC.\n *\n * You shouldn't usually call this method directly as it is called\n * implicitly the first time you call {@link call}.\n */\n async connect(): Promise<void> {\n if (this._connected) {\n // avoid double-connect\n await this._connected\n\n return\n }\n\n const promise = (this._connected = createControllablePromise())\n\n await this._loadStorage()\n const primaryDc = await this.storage.getDefaultDcs()\n if (primaryDc !== null) this._defaultDcs = primaryDc\n\n const defaultDcAuthKey = await this.storage.getAuthKeyFor(this._defaultDcs.main.id)\n\n if ((this._importForce || !defaultDcAuthKey) && this._importFrom) {\n const data = readStringSession(this._readerMap, this._importFrom)\n\n if (data.testMode !== this._testMode) {\n throw new Error(\n 'This session string is not for the current backend. ' +\n `Session is ${data.testMode ? 'test' : 'prod'}, but the client is ${\n this._testMode ? 'test' : 'prod'\n }`,\n )\n }\n\n this._defaultDcs = data.primaryDcs\n await this.storage.setDefaultDcs(data.primaryDcs)\n\n if (data.self) {\n await this.storage.setSelf(data.self)\n }\n\n // await this.primaryConnection.setupKeys(data.authKey)\n await this.storage.setAuthKeyFor(data.primaryDcs.main.id, data.authKey)\n\n await this.saveStorage()\n }\n\n this.emit('before_connect')\n\n this.network\n .connect(this._defaultDcs)\n .then(() => {\n promise.resolve()\n this._connected = true\n })\n .catch((err: Error) => this._emitError(err))\n }\n\n /**\n * Close all connections and finalize the client.\n */\n async close(): Promise<void> {\n this.emit('before_close')\n\n this._config.destroy()\n this.network.destroy()\n\n await this.saveStorage()\n await this.storage.destroy?.()\n\n this.emit('closed')\n }\n\n /**\n * Make an RPC call to the primary DC.\n * This method handles DC migration, flood waits and retries automatically.\n *\n * If you want more low-level control, use\n * `primaryConnection.sendForResult()` (which is what this method wraps)\n *\n * This method is still quite low-level and you shouldn't use this\n * when using high-level API provided by `@mtcute/client`.\n *\n * @param message RPC method to call\n * @param params Additional call parameters\n */\n async call<T extends tl.RpcMethod>(\n message: MustEqual<T, tl.RpcMethod>,\n params?: RpcCallOptions,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n if (this._connected !== true) {\n await this.connect()\n }\n\n const stack = this._niceStacks ? new Error().stack : undefined\n\n const res = await this.network.call(message, params, stack)\n await this._cachePeersFrom(res)\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return res\n }\n\n /**\n * Change transport for the client.\n *\n * Can be used, for example, to change proxy at runtime\n *\n * This effectively calls `changeTransport()` on\n * `primaryConnection` and all additional connections.\n *\n * @param factory New transport factory\n */\n changeTransport(factory: TransportFactory): void {\n this.network.changeTransport(factory)\n }\n\n /**\n * Register an error handler for the client\n *\n * @param handler\n * Error handler. Called with one or two parameters.\n * The first one is always the error, and the second is\n * the connection in which the error has occurred, in case\n * this was connection-related error.\n */\n onError(handler: (err: unknown, connection?: SessionConnection) => void): void {\n this._onError = handler\n }\n\n notifyLoggedIn(auth: tl.auth.RawAuthorization): void {\n this.network.notifyLoggedIn(auth)\n this.emit('logged_in', auth)\n }\n\n _emitError(err: unknown, connection?: SessionConnection): void {\n if (this._onError) {\n this._onError(err, connection)\n } else {\n console.error(err)\n }\n }\n\n /**\n * Adds all peers from a given object to entity cache in storage.\n *\n * @returns `true` if there were any `min` peers\n */\n async _cachePeersFrom(obj: object): Promise<boolean> {\n const parsedPeers: ITelegramStorage.PeerInfo[] = []\n\n let hadMin = false\n let count = 0\n\n for (const peer of getAllPeersFrom(obj as tl.TlObject)) {\n if ((peer as any).min) {\n // absolutely incredible min peer handling, courtesy of levlam.\n // see this thread: https://t.me/tdlibchat/15084\n hadMin = true\n this.log.debug('received min peer: %j', peer)\n continue\n }\n\n count += 1\n\n switch (peer._) {\n case 'user':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n\n parsedPeers.push({\n id: peer.id,\n accessHash: peer.accessHash,\n username: peer.username?.toLowerCase(),\n phone: peer.phone,\n type: 'user',\n full: peer,\n })\n break\n case 'chat':\n case 'chatForbidden':\n parsedPeers.push({\n id: -peer.id,\n accessHash: Long.ZERO,\n type: 'chat',\n full: peer,\n })\n break\n case 'channel':\n case 'channelForbidden':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n parsedPeers.push({\n id: toggleChannelIdMark(peer.id),\n accessHash: peer.accessHash,\n username: peer._ === 'channel' ? peer.username?.toLowerCase() : undefined,\n type: 'channel',\n full: peer,\n })\n break\n }\n }\n\n if (count > 0) {\n await this.storage.updatePeers(parsedPeers)\n this.log.debug('cached %d peers', count)\n }\n\n return hadMin\n }\n\n /**\n * Export current session to a single *LONG* string, containing\n * all the needed information.\n *\n * > **Warning!** Anyone with this string will be able\n * > to authorize as you and do anything. Treat this\n * > as your password, and never give it away!\n * >\n * > In case you have accidentally leaked this string,\n * > make sure to revoke this session in account settings:\n * > \"Privacy & Security\" > \"Active sessions\" >\n * > find the one containing `mtcute` > Revoke,\n * > or, in case this is a bot, revoke bot token\n * > with [@BotFather](//t.me/botfather)\n */\n async exportSession(): Promise<string> {\n const primaryDcs = await this.storage.getDefaultDcs()\n if (!primaryDcs) throw new Error('No default DC set')\n\n const authKey = await this.storage.getAuthKeyFor(primaryDcs.main.id)\n if (!authKey) throw new Error('Auth key is not ready yet')\n\n return writeStringSession(this._writerMap, {\n version: 2,\n self: await this.storage.getSelf(),\n testMode: this._testMode,\n primaryDcs,\n authKey,\n })\n }\n\n /**\n * Request the session to be imported from the given session string.\n *\n * Note that the string will not be parsed and imported right away,\n * instead, it will be imported when `connect()` is called\n *\n * Also note that the session will only be imported in case\n * the storage is missing authorization (i.e. does not contain\n * auth key for the primary DC), otherwise it will be ignored (unless `force).\n *\n * @param session Session string to import\n * @param force Whether to overwrite existing session\n */\n importSession(session: string, force = false): void {\n this._importFrom = session\n this._importForce = force\n }\n}\n"]}
1
+ {"version":3,"file":"base-client.js","sourceRoot":"","sources":["../../src/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport EventEmitter from 'events'\nimport Long from 'long'\n\nimport { tl } from '@mtcute/tl'\nimport { __tlReaderMap as defaultReaderMap } from '@mtcute/tl/binary/reader.js'\nimport { __tlWriterMap as defaultWriterMap } from '@mtcute/tl/binary/writer.js'\nimport { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'\n\nimport { ConfigManager } from './network/config-manager.js'\nimport { ReconnectionStrategy, SessionConnection, TransportFactory } from './network/index.js'\nimport { NetworkManager, NetworkManagerExtraParams, RpcCallOptions } from './network/network-manager.js'\nimport { PersistentConnectionParams } from './network/persistent-connection.js'\nimport { ITelegramStorage, MemoryStorage } from './storage/index.js'\nimport { MustEqual } from './types/index.js'\nimport {\n ControllablePromise,\n createControllablePromise,\n CryptoProviderFactory,\n defaultCryptoProviderFactory,\n defaultProductionDc,\n defaultProductionIpv6Dc,\n defaultTestDc,\n defaultTestIpv6Dc,\n getAllPeersFrom,\n ICryptoProvider,\n LogManager,\n readStringSession,\n toggleChannelIdMark,\n writeStringSession,\n} from './utils/index.js'\n\n/** Options for {@link BaseTelegramClient} */\nexport interface BaseTelegramClientOptions {\n /**\n * API ID from my.telegram.org\n */\n apiId: number | string\n /**\n * API hash from my.telegram.org\n */\n apiHash: string\n\n /**\n * Telegram storage to use.\n * If omitted, {@link MemoryStorage} is used\n */\n storage?: ITelegramStorage\n\n /**\n * Cryptography provider factory to allow delegating\n * crypto to native addon, worker, etc.\n */\n crypto?: CryptoProviderFactory\n\n /**\n * Whether to use IPv6 datacenters\n * (IPv6 will be preferred when choosing a DC by id)\n * (default: false)\n */\n useIpv6?: boolean\n\n /**\n * Primary DC to use for initial connection.\n * This does not mean this will be the only DC used,\n * nor that this DC will actually be primary, this only\n * determines the first DC the library will try to connect to.\n * Can be used to connect to other networks (like test DCs).\n *\n * When session already contains primary DC, this parameter is ignored.\n *\n * @default Production DC 2.\n */\n defaultDcs?: ITelegramStorage.DcOptions\n\n /**\n * Whether to connect to test servers.\n *\n * If passed, {@link defaultDc} defaults to Test DC 2.\n *\n * **Must** be passed if using test servers, even if\n * you passed custom {@link defaultDc}\n */\n testMode?: boolean\n\n /**\n * Additional options for initConnection call.\n * `apiId` and `query` are not available and will be ignored.\n * Omitted values will be filled with defaults\n */\n initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>\n\n /**\n * Transport factory to use in the client.\n *\n * @default platform-specific transport: WebSocket on the web, TCP in node\n */\n transport?: TransportFactory\n\n /**\n * Reconnection strategy.\n *\n * @default simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)\n */\n reconnectionStrategy?: ReconnectionStrategy<PersistentConnectionParams>\n\n /**\n * Maximum duration of a flood_wait that will be waited automatically.\n * Flood waits above this threshold will throw a FloodWaitError.\n * Set to 0 to disable. Can be overridden with `throwFlood` parameter in call() params\n *\n * @default 10000\n */\n floodSleepThreshold?: number\n\n /**\n * Maximum number of retries when calling RPC methods.\n * Call is retried when InternalError or FloodWaitError is encountered.\n * Can be set to Infinity.\n *\n * @default 5\n */\n maxRetryCount?: number\n\n /**\n * If true, every single API call will be wrapped with `tl.invokeWithoutUpdates`,\n * effectively disabling the server-sent events for the clients.\n * May be useful in some cases.\n *\n * Note that this only wraps calls made with `.call()` within the primary\n * connection. Additional connections and direct `.sendForResult()` calls\n * must be wrapped manually.\n *\n * @default false\n */\n disableUpdates?: boolean\n\n /**\n * mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s\n * [error reporting service](https://rpc.pwrtelegram.xyz/).\n *\n * This is fully anonymous (except maybe IP) and is only used to improve the library\n * and developer experience for everyone working with MTProto. This is fully opt-in,\n * and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.\n *\n * @default false\n */\n enableErrorReporting?: boolean\n\n /**\n * If true, RPC errors will have a stack trace of the initial `.call()`\n * or `.sendForResult()` call position, which drastically improves\n * debugging experience.<br>\n * If false, they will have a stack trace of mtcute internals.\n *\n * Internally this creates a stack capture before every RPC call\n * and stores it until the result is received. This might\n * use a lot more memory than normal, thus can be disabled here.\n *\n * @default true\n */\n niceStacks?: boolean\n\n /**\n * Extra parameters for {@link NetworkManager}\n */\n network?: NetworkManagerExtraParams\n\n /**\n * Set logging level for the client.\n *\n * See static members of {@link LogManager} for possible values.\n */\n logLevel?: number\n\n /**\n * **EXPERT USE ONLY!**\n *\n * Override TL layer used for the connection.\n *\n * **Does not** change the schema used.\n */\n overrideLayer?: number\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override reader map used for the connection.\n */\n readerMap?: TlReaderMap\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override writer map used for the connection.\n */\n writerMap?: TlWriterMap\n}\n\n/**\n * Basic Telegram client that only implements the bare minimum\n * to make RPC calls and receive low-level updates.\n */\nexport class BaseTelegramClient extends EventEmitter {\n /**\n * Crypto provider taken from {@link BaseTelegramClientOptions.crypto}\n */\n readonly crypto: ICryptoProvider\n\n /**\n * Telegram storage taken from {@link BaseTelegramClientOptions.storage}\n */\n readonly storage: ITelegramStorage\n\n /**\n * API hash taken from {@link BaseTelegramClientOptions.apiHash}\n */\n protected readonly _apiHash: string\n\n /**\n * \"Use IPv6\" taken from {@link BaseTelegramClientOptions.useIpv6}\n */\n protected readonly _useIpv6: boolean\n\n /**\n * \"Test mode\" taken from {@link BaseTelegramClientOptions.testMode}\n */\n protected readonly _testMode: boolean\n\n /**\n * Primary DCs taken from {@link BaseTelegramClientOptions.defaultDcs},\n * loaded from session or changed by other means (like redirecting).\n */\n protected _defaultDcs: ITelegramStorage.DcOptions\n\n private _niceStacks: boolean\n /** TL layer used by the client */\n readonly _layer: number\n /** TL readers map used by the client */\n readonly _readerMap: TlReaderMap\n /** TL writers map used by the client */\n readonly _writerMap: TlWriterMap\n\n /** Unix timestamp when the last update was received */\n protected _lastUpdateTime = 0\n\n readonly _config = new ConfigManager(() => this.call({ _: 'help.getConfig' }))\n\n // not really connected, but rather \"connect() was called\"\n private _connected: ControllablePromise<void> | boolean = false\n\n private _onError?: (err: unknown, connection?: SessionConnection) => void\n\n private _importFrom?: string\n private _importForce?: boolean\n\n readonly log = new LogManager('client')\n readonly network: NetworkManager\n\n constructor(opts: BaseTelegramClientOptions) {\n super()\n\n const apiId = typeof opts.apiId === 'string' ? parseInt(opts.apiId) : opts.apiId\n\n if (isNaN(apiId)) {\n throw new Error('apiId must be a number or a numeric string!')\n }\n\n if (opts.logLevel !== undefined) {\n this.log.level = opts.logLevel\n }\n\n this.crypto = (opts.crypto ?? defaultCryptoProviderFactory)()\n this.storage = opts.storage ?? new MemoryStorage()\n this._apiHash = opts.apiHash\n this._useIpv6 = Boolean(opts.useIpv6)\n this._testMode = Boolean(opts.testMode)\n\n let dc = opts.defaultDcs\n\n if (!dc) {\n if (this._testMode) {\n dc = this._useIpv6 ? defaultTestIpv6Dc : defaultTestDc\n } else {\n dc = this._useIpv6 ? defaultProductionIpv6Dc : defaultProductionDc\n }\n }\n\n this._defaultDcs = dc\n this._niceStacks = opts.niceStacks ?? true\n\n this._layer = opts.overrideLayer ?? tl.LAYER\n this._readerMap = opts.readerMap ?? defaultReaderMap\n this._writerMap = opts.writerMap ?? defaultWriterMap\n\n this.network = new NetworkManager(\n {\n apiId,\n crypto: this.crypto,\n disableUpdates: opts.disableUpdates ?? false,\n initConnectionOptions: opts.initConnectionOptions,\n layer: this._layer,\n log: this.log,\n readerMap: this._readerMap,\n writerMap: this._writerMap,\n reconnectionStrategy: opts.reconnectionStrategy,\n storage: this.storage,\n testMode: this._testMode,\n transport: opts.transport,\n _emitError: this._emitError.bind(this),\n floodSleepThreshold: opts.floodSleepThreshold ?? 10000,\n maxRetryCount: opts.maxRetryCount ?? 5,\n isPremium: false,\n useIpv6: Boolean(opts.useIpv6),\n keepAliveAction: this._keepAliveAction.bind(this),\n enableErrorReporting: opts.enableErrorReporting ?? false,\n onUsable: () => this.emit('usable'),\n ...(opts.network ?? {}),\n },\n this._config,\n )\n\n this.storage.setup?.(this.log, this._readerMap, this._writerMap)\n }\n\n protected _keepAliveAction(): void {\n this.emit('keep_alive')\n }\n\n protected async _loadStorage(): Promise<void> {\n await this.storage.load?.()\n }\n\n _beforeStorageSave: (() => Promise<void>)[] = []\n\n beforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave.push(cb)\n }\n\n offBeforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave = this._beforeStorageSave.filter((x) => x !== cb)\n }\n\n async saveStorage(): Promise<void> {\n for (const cb of this._beforeStorageSave) {\n await cb()\n }\n await this.storage.save?.()\n }\n\n /**\n * Initialize the connection to the primary DC.\n *\n * You shouldn't usually call this method directly as it is called\n * implicitly the first time you call {@link call}.\n */\n async connect(): Promise<void> {\n if (this._connected) {\n // avoid double-connect\n await this._connected\n\n return\n }\n\n const promise = (this._connected = createControllablePromise())\n\n await this.crypto.initialize?.()\n await this._loadStorage()\n const primaryDc = await this.storage.getDefaultDcs()\n if (primaryDc !== null) this._defaultDcs = primaryDc\n\n const defaultDcAuthKey = await this.storage.getAuthKeyFor(this._defaultDcs.main.id)\n\n if ((this._importForce || !defaultDcAuthKey) && this._importFrom) {\n const data = readStringSession(this._readerMap, this._importFrom)\n\n if (data.testMode !== this._testMode) {\n throw new Error(\n 'This session string is not for the current backend. ' +\n `Session is ${data.testMode ? 'test' : 'prod'}, but the client is ${\n this._testMode ? 'test' : 'prod'\n }`,\n )\n }\n\n this._defaultDcs = data.primaryDcs\n await this.storage.setDefaultDcs(data.primaryDcs)\n\n if (data.self) {\n await this.storage.setSelf(data.self)\n }\n\n // await this.primaryConnection.setupKeys(data.authKey)\n await this.storage.setAuthKeyFor(data.primaryDcs.main.id, data.authKey)\n\n await this.saveStorage()\n }\n\n this.emit('before_connect')\n\n this.network\n .connect(this._defaultDcs)\n .then(() => {\n promise.resolve()\n this._connected = true\n })\n .catch((err: Error) => this._emitError(err))\n }\n\n /**\n * Close all connections and finalize the client.\n */\n async close(): Promise<void> {\n this.emit('before_close')\n\n this._config.destroy()\n this.network.destroy()\n\n await this.saveStorage()\n await this.storage.destroy?.()\n\n this.emit('closed')\n }\n\n /**\n * Make an RPC call to the primary DC.\n * This method handles DC migration, flood waits and retries automatically.\n *\n * If you want more low-level control, use\n * `primaryConnection.sendForResult()` (which is what this method wraps)\n *\n * This method is still quite low-level and you shouldn't use this\n * when using high-level API provided by `@mtcute/client`.\n *\n * @param message RPC method to call\n * @param params Additional call parameters\n */\n async call<T extends tl.RpcMethod>(\n message: MustEqual<T, tl.RpcMethod>,\n params?: RpcCallOptions,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n if (this._connected !== true) {\n await this.connect()\n }\n\n const stack = this._niceStacks ? new Error().stack : undefined\n\n const res = await this.network.call(message, params, stack)\n await this._cachePeersFrom(res)\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return res\n }\n\n /**\n * Change transport for the client.\n *\n * Can be used, for example, to change proxy at runtime\n *\n * This effectively calls `changeTransport()` on\n * `primaryConnection` and all additional connections.\n *\n * @param factory New transport factory\n */\n changeTransport(factory: TransportFactory): void {\n this.network.changeTransport(factory)\n }\n\n /**\n * Register an error handler for the client\n *\n * @param handler\n * Error handler. Called with one or two parameters.\n * The first one is always the error, and the second is\n * the connection in which the error has occurred, in case\n * this was connection-related error.\n */\n onError(handler: (err: unknown, connection?: SessionConnection) => void): void {\n this._onError = handler\n }\n\n notifyLoggedIn(auth: tl.auth.RawAuthorization): void {\n this.network.notifyLoggedIn(auth)\n this.emit('logged_in', auth)\n }\n\n _emitError(err: unknown, connection?: SessionConnection): void {\n if (this._onError) {\n this._onError(err, connection)\n } else {\n console.error(err)\n }\n }\n\n /**\n * Adds all peers from a given object to entity cache in storage.\n *\n * @returns `true` if there were any `min` peers\n */\n async _cachePeersFrom(obj: object): Promise<boolean> {\n const parsedPeers: ITelegramStorage.PeerInfo[] = []\n\n let hadMin = false\n let count = 0\n\n for (const peer of getAllPeersFrom(obj as tl.TlObject)) {\n if ((peer as any).min) {\n // absolutely incredible min peer handling, courtesy of levlam.\n // see this thread: https://t.me/tdlibchat/15084\n hadMin = true\n this.log.debug('received min peer: %j', peer)\n continue\n }\n\n count += 1\n\n switch (peer._) {\n case 'user':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n\n parsedPeers.push({\n id: peer.id,\n accessHash: peer.accessHash,\n username: peer.username?.toLowerCase(),\n phone: peer.phone,\n type: 'user',\n full: peer,\n })\n break\n case 'chat':\n case 'chatForbidden':\n parsedPeers.push({\n id: -peer.id,\n accessHash: Long.ZERO,\n type: 'chat',\n full: peer,\n })\n break\n case 'channel':\n case 'channelForbidden':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n parsedPeers.push({\n id: toggleChannelIdMark(peer.id),\n accessHash: peer.accessHash,\n username: peer._ === 'channel' ? peer.username?.toLowerCase() : undefined,\n type: 'channel',\n full: peer,\n })\n break\n }\n }\n\n if (count > 0) {\n await this.storage.updatePeers(parsedPeers)\n this.log.debug('cached %d peers', count)\n }\n\n return hadMin\n }\n\n /**\n * Export current session to a single *LONG* string, containing\n * all the needed information.\n *\n * > **Warning!** Anyone with this string will be able\n * > to authorize as you and do anything. Treat this\n * > as your password, and never give it away!\n * >\n * > In case you have accidentally leaked this string,\n * > make sure to revoke this session in account settings:\n * > \"Privacy & Security\" > \"Active sessions\" >\n * > find the one containing `mtcute` > Revoke,\n * > or, in case this is a bot, revoke bot token\n * > with [@BotFather](//t.me/botfather)\n */\n async exportSession(): Promise<string> {\n const primaryDcs = await this.storage.getDefaultDcs()\n if (!primaryDcs) throw new Error('No default DC set')\n\n const authKey = await this.storage.getAuthKeyFor(primaryDcs.main.id)\n if (!authKey) throw new Error('Auth key is not ready yet')\n\n return writeStringSession(this._writerMap, {\n version: 2,\n self: await this.storage.getSelf(),\n testMode: this._testMode,\n primaryDcs,\n authKey,\n })\n }\n\n /**\n * Request the session to be imported from the given session string.\n *\n * Note that the string will not be parsed and imported right away,\n * instead, it will be imported when `connect()` is called\n *\n * Also note that the session will only be imported in case\n * the storage is missing authorization (i.e. does not contain\n * auth key for the primary DC), otherwise it will be ignored (unless `force).\n *\n * @param session Session string to import\n * @param force Whether to overwrite existing session\n */\n importSession(session: string, force = false): void {\n this._importFrom = session\n this._importForce = force\n }\n}\n"]}
@@ -13,9 +13,9 @@ export declare class AuthKey {
13
13
  serverSalt: Uint8Array;
14
14
  constructor(_crypto: ICryptoProvider, log: Logger, _readerMap: TlReaderMap);
15
15
  match(keyId: Uint8Array): boolean;
16
- setup(authKey?: Uint8Array | null): Promise<void>;
17
- encryptMessage(message: Uint8Array, serverSalt: Long, sessionId: Long): Promise<Uint8Array>;
18
- decryptMessage(data: Uint8Array, sessionId: Long, callback: (msgId: tl.Long, seqNo: number, data: TlBinaryReader) => void): Promise<void>;
16
+ setup(authKey?: Uint8Array | null): void;
17
+ encryptMessage(message: Uint8Array, serverSalt: Long, sessionId: Long): Uint8Array;
18
+ decryptMessage(data: Uint8Array, sessionId: Long, callback: (msgId: tl.Long, seqNo: number, data: TlBinaryReader) => void): void;
19
19
  copyFrom(authKey: AuthKey): void;
20
20
  reset(): void;
21
21
  }
@@ -1,7 +1,7 @@
1
1
  import { TlBinaryReader } from '@mtcute/tl-runtime';
2
2
  import { MtcuteError } from '../types/errors.js';
3
3
  import { createAesIgeForMessage } from '../utils/crypto/mtproto.js';
4
- import { buffersEqual, concatBuffers, dataViewFromBuffer, randomBytes } from '../utils/index.js';
4
+ import { buffersEqual, concatBuffers, dataViewFromBuffer } from '../utils/index.js';
5
5
  export class AuthKey {
6
6
  constructor(_crypto, log, _readerMap) {
7
7
  this._crypto = _crypto;
@@ -12,17 +12,17 @@ export class AuthKey {
12
12
  match(keyId) {
13
13
  return this.ready && buffersEqual(keyId, this.id);
14
14
  }
15
- async setup(authKey) {
15
+ setup(authKey) {
16
16
  if (!authKey)
17
17
  return this.reset();
18
18
  this.ready = true;
19
19
  this.key = authKey;
20
20
  this.clientSalt = authKey.subarray(88, 120);
21
21
  this.serverSalt = authKey.subarray(96, 128);
22
- this.id = (await this._crypto.sha1(authKey)).subarray(-8);
22
+ this.id = this._crypto.sha1(authKey).subarray(-8);
23
23
  this.log.verbose('auth key set up, id = %h', this.id);
24
24
  }
25
- async encryptMessage(message, serverSalt, sessionId) {
25
+ encryptMessage(message, serverSalt, sessionId) {
26
26
  if (!this.ready)
27
27
  throw new MtcuteError('Keys are not set up!');
28
28
  let padding = (16 /* header size */ + message.length + 12) /* min padding */ % 16;
@@ -34,13 +34,13 @@ export class AuthKey {
34
34
  dv.setInt32(8, sessionId.low, true);
35
35
  dv.setInt32(12, sessionId.high, true);
36
36
  buf.set(message, 16);
37
- buf.set(randomBytes(padding), 16 + message.length);
38
- const messageKey = (await this._crypto.sha256(concatBuffers([this.clientSalt, buf]))).subarray(8, 24);
39
- const ige = await createAesIgeForMessage(this._crypto, this.key, messageKey, true);
40
- const encryptedData = await ige.encrypt(buf);
37
+ this._crypto.randomFill(buf.subarray(16 + message.length, 16 + message.length + padding));
38
+ const messageKey = this._crypto.sha256(concatBuffers([this.clientSalt, buf])).subarray(8, 24);
39
+ const ige = createAesIgeForMessage(this._crypto, this.key, messageKey, true);
40
+ const encryptedData = ige.encrypt(buf);
41
41
  return concatBuffers([this.id, messageKey, encryptedData]);
42
42
  }
43
- async decryptMessage(data, sessionId, callback) {
43
+ decryptMessage(data, sessionId, callback) {
44
44
  const messageKey = data.subarray(8, 24);
45
45
  let encryptedData = data.subarray(24);
46
46
  const mod16 = encryptedData.byteLength % 16;
@@ -50,12 +50,12 @@ export class AuthKey {
50
50
  // because padding size is not known, and transport level should not be aware of MTProto structure
51
51
  encryptedData = encryptedData.subarray(0, encryptedData.byteLength - mod16);
52
52
  }
53
- const ige = await createAesIgeForMessage(this._crypto, this.key, messageKey, false);
54
- const innerData = await ige.decrypt(encryptedData);
55
- const msgKeySource = await this._crypto.sha256(concatBuffers([this.serverSalt, innerData]));
53
+ const ige = createAesIgeForMessage(this._crypto, this.key, messageKey, false);
54
+ const innerData = ige.decrypt(encryptedData);
55
+ const msgKeySource = this._crypto.sha256(concatBuffers([this.serverSalt, innerData]));
56
56
  const expectedMessageKey = msgKeySource.subarray(8, 24);
57
57
  if (!buffersEqual(messageKey, expectedMessageKey)) {
58
- this.log.warn('[%h] received message with invalid messageKey = %h (expected %h)', messageKey, expectedMessageKey);
58
+ this.log.warn('received message with invalid messageKey = %h (expected %h)', messageKey, expectedMessageKey);
59
59
  return;
60
60
  }
61
61
  const innerReader = new TlBinaryReader(this._readerMap, innerData);
@@ -1 +1 @@
1
- {"version":3,"file":"auth-key.js","sourceRoot":"","sources":["../../../src/network/auth-key.ts"],"names":[],"mappings":"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","sourcesContent":["import Long from 'long'\n\nimport { tl } from '@mtcute/tl'\nimport { TlBinaryReader, TlReaderMap } from '@mtcute/tl-runtime'\n\nimport { MtcuteError } from '../types/errors.js'\nimport { createAesIgeForMessage } from '../utils/crypto/mtproto.js'\nimport { buffersEqual, concatBuffers, dataViewFromBuffer, ICryptoProvider, Logger, randomBytes } from '../utils/index.js'\n\nexport class AuthKey {\n ready = false\n\n key!: Uint8Array\n id!: Uint8Array\n clientSalt!: Uint8Array\n serverSalt!: Uint8Array\n\n constructor(\n readonly _crypto: ICryptoProvider,\n readonly log: Logger,\n readonly _readerMap: TlReaderMap,\n ) {}\n\n match(keyId: Uint8Array): boolean {\n return this.ready && buffersEqual(keyId, this.id)\n }\n\n async setup(authKey?: Uint8Array | null): Promise<void> {\n if (!authKey) return this.reset()\n\n this.ready = true\n this.key = authKey\n this.clientSalt = authKey.subarray(88, 120)\n this.serverSalt = authKey.subarray(96, 128)\n this.id = (await this._crypto.sha1(authKey)).subarray(-8)\n\n this.log.verbose('auth key set up, id = %h', this.id)\n }\n\n async encryptMessage(message: Uint8Array, serverSalt: Long, sessionId: Long): Promise<Uint8Array> {\n if (!this.ready) throw new MtcuteError('Keys are not set up!')\n\n let padding = (16 /* header size */ + message.length + 12) /* min padding */ % 16\n padding = 12 + (padding ? 16 - padding : 0)\n\n const buf = new Uint8Array(16 + message.length + padding)\n const dv = dataViewFromBuffer(buf)\n\n dv.setInt32(0, serverSalt.low, true)\n dv.setInt32(4, serverSalt.high, true)\n dv.setInt32(8, sessionId.low, true)\n dv.setInt32(12, sessionId.high, true)\n buf.set(message, 16)\n buf.set(randomBytes(padding), 16 + message.length)\n\n const messageKey = (await this._crypto.sha256(concatBuffers([this.clientSalt, buf]))).subarray(8, 24)\n const ige = await createAesIgeForMessage(this._crypto, this.key, messageKey, true)\n const encryptedData = await ige.encrypt(buf)\n\n return concatBuffers([this.id, messageKey, encryptedData])\n }\n\n async decryptMessage(\n data: Uint8Array,\n sessionId: Long,\n callback: (msgId: tl.Long, seqNo: number, data: TlBinaryReader) => void,\n ): Promise<void> {\n const messageKey = data.subarray(8, 24)\n let encryptedData = data.subarray(24)\n\n const mod16 = encryptedData.byteLength % 16\n\n if (mod16 !== 0) {\n // strip padding in case of padded transport.\n // i wish this could be done at transport level, but we can't properly align anything there\n // because padding size is not known, and transport level should not be aware of MTProto structure\n encryptedData = encryptedData.subarray(0, encryptedData.byteLength - mod16)\n }\n\n const ige = await createAesIgeForMessage(this._crypto, this.key, messageKey, false)\n const innerData = await ige.decrypt(encryptedData)\n\n const msgKeySource = await this._crypto.sha256(concatBuffers([this.serverSalt, innerData]))\n const expectedMessageKey = msgKeySource.subarray(8, 24)\n\n if (!buffersEqual(messageKey, expectedMessageKey)) {\n this.log.warn(\n '[%h] received message with invalid messageKey = %h (expected %h)',\n messageKey,\n expectedMessageKey,\n )\n\n return\n }\n\n const innerReader = new TlBinaryReader(this._readerMap, innerData)\n innerReader.seek(8) // skip salt\n const sessionId_ = innerReader.long()\n const messageId = innerReader.long(true)\n\n if (sessionId_.neq(sessionId)) {\n this.log.warn('ignoring message with invalid sessionId = %h', sessionId_)\n\n return\n }\n\n const seqNo = innerReader.uint()\n const length = innerReader.uint()\n\n if (length > innerData.length - 32 /* header size */) {\n this.log.warn('ignoring message with invalid length: %d > %d', length, innerData.length - 32)\n\n return\n }\n\n if (length % 4 !== 0) {\n this.log.warn('ignoring message with invalid length: %d is not a multiple of 4', length)\n\n return\n }\n\n const paddingSize = innerData.length - length - 32 // header size\n\n if (paddingSize < 12 || paddingSize > 1024) {\n this.log.warn('ignoring message with invalid padding size: %d', paddingSize)\n\n return\n }\n\n callback(messageId, seqNo, innerReader)\n }\n\n copyFrom(authKey: AuthKey): void {\n this.ready = authKey.ready\n this.key = authKey.key\n this.id = authKey.id\n this.serverSalt = authKey.serverSalt\n this.clientSalt = authKey.clientSalt\n }\n\n reset(): void {\n this.ready = false\n }\n}\n"]}
1
+ {"version":3,"file":"auth-key.js","sourceRoot":"","sources":["../../../src/network/auth-key.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAe,MAAM,oBAAoB,CAAA;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAA2B,MAAM,mBAAmB,CAAA;AAE5G,MAAM,OAAO,OAAO;IAQhB,YACa,OAAwB,EACxB,GAAW,EACX,UAAuB;QAFvB,YAAO,GAAP,OAAO,CAAiB;QACxB,QAAG,GAAH,GAAG,CAAQ;QACX,eAAU,GAAV,UAAU,CAAa;QAVpC,UAAK,GAAG,KAAK,CAAA;IAWV,CAAC;IAEJ,KAAK,CAAC,KAAiB;QACnB,OAAO,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;IACrD,CAAC;IAED,KAAK,CAAC,OAA2B;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,CAAA;QAEjC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAA;QAClB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAEjD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,0BAA0B,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;IACzD,CAAC;IAED,cAAc,CAAC,OAAmB,EAAE,UAAgB,EAAE,SAAe;QACjE,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,WAAW,CAAC,sBAAsB,CAAC,CAAA;QAE9D,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,iBAAiB,GAAG,EAAE,CAAA;QACjF,OAAO,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAE3C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CAAA;QACzD,MAAM,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAElC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACpC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACrC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACnC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACrC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QACpB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAA;QAEzF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC7F,MAAM,GAAG,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;QAC5E,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAEtC,OAAO,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,cAAc,CACV,IAAgB,EAChB,SAAe,EACf,QAAuE;QAEvE,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACvC,IAAI,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;QAErC,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,GAAG,EAAE,CAAA;QAE3C,IAAI,KAAK,KAAK,CAAC,EAAE;YACb,6CAA6C;YAC7C,2FAA2F;YAC3F,kGAAkG;YAClG,aAAa,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,EAAE,aAAa,CAAC,UAAU,GAAG,KAAK,CAAC,CAAA;SAC9E;QAED,MAAM,GAAG,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;QAC7E,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;QACrF,MAAM,kBAAkB,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAEvD,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,kBAAkB,CAAC,EAAE;YAC/C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6DAA6D,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAA;YAE5G,OAAM;SACT;QAED,MAAM,WAAW,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;QAClE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,YAAY;QAChC,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,EAAE,CAAA;QACrC,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAExC,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,8CAA8C,EAAE,UAAU,CAAC,CAAA;YAEzE,OAAM;SACT;QAED,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAA;QAChC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,CAAA;QAEjC,IAAI,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,iBAAiB,EAAE;YAClD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,+CAA+C,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;YAE7F,OAAM;SACT;QAED,IAAI,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE;YAClB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iEAAiE,EAAE,MAAM,CAAC,CAAA;YAExF,OAAM;SACT;QAED,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,GAAG,EAAE,CAAA,CAAC,cAAc;QAEjE,IAAI,WAAW,GAAG,EAAE,IAAI,WAAW,GAAG,IAAI,EAAE;YACxC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,EAAE,WAAW,CAAC,CAAA;YAE5E,OAAM;SACT;QAED,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,CAAC,CAAA;IAC3C,CAAC;IAED,QAAQ,CAAC,OAAgB;QACrB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1B,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAA;QACpB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAA;QACpC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAA;IACxC,CAAC;IAED,KAAK;QACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACtB,CAAC;CACJ","sourcesContent":["import Long from 'long'\n\nimport { tl } from '@mtcute/tl'\nimport { TlBinaryReader, TlReaderMap } from '@mtcute/tl-runtime'\n\nimport { MtcuteError } from '../types/errors.js'\nimport { createAesIgeForMessage } from '../utils/crypto/mtproto.js'\nimport { buffersEqual, concatBuffers, dataViewFromBuffer, ICryptoProvider, Logger } from '../utils/index.js'\n\nexport class AuthKey {\n ready = false\n\n key!: Uint8Array\n id!: Uint8Array\n clientSalt!: Uint8Array\n serverSalt!: Uint8Array\n\n constructor(\n readonly _crypto: ICryptoProvider,\n readonly log: Logger,\n readonly _readerMap: TlReaderMap,\n ) {}\n\n match(keyId: Uint8Array): boolean {\n return this.ready && buffersEqual(keyId, this.id)\n }\n\n setup(authKey?: Uint8Array | null): void {\n if (!authKey) return this.reset()\n\n this.ready = true\n this.key = authKey\n this.clientSalt = authKey.subarray(88, 120)\n this.serverSalt = authKey.subarray(96, 128)\n this.id = this._crypto.sha1(authKey).subarray(-8)\n\n this.log.verbose('auth key set up, id = %h', this.id)\n }\n\n encryptMessage(message: Uint8Array, serverSalt: Long, sessionId: Long): Uint8Array {\n if (!this.ready) throw new MtcuteError('Keys are not set up!')\n\n let padding = (16 /* header size */ + message.length + 12) /* min padding */ % 16\n padding = 12 + (padding ? 16 - padding : 0)\n\n const buf = new Uint8Array(16 + message.length + padding)\n const dv = dataViewFromBuffer(buf)\n\n dv.setInt32(0, serverSalt.low, true)\n dv.setInt32(4, serverSalt.high, true)\n dv.setInt32(8, sessionId.low, true)\n dv.setInt32(12, sessionId.high, true)\n buf.set(message, 16)\n this._crypto.randomFill(buf.subarray(16 + message.length, 16 + message.length + padding))\n\n const messageKey = this._crypto.sha256(concatBuffers([this.clientSalt, buf])).subarray(8, 24)\n const ige = createAesIgeForMessage(this._crypto, this.key, messageKey, true)\n const encryptedData = ige.encrypt(buf)\n\n return concatBuffers([this.id, messageKey, encryptedData])\n }\n\n decryptMessage(\n data: Uint8Array,\n sessionId: Long,\n callback: (msgId: tl.Long, seqNo: number, data: TlBinaryReader) => void,\n ): void {\n const messageKey = data.subarray(8, 24)\n let encryptedData = data.subarray(24)\n\n const mod16 = encryptedData.byteLength % 16\n\n if (mod16 !== 0) {\n // strip padding in case of padded transport.\n // i wish this could be done at transport level, but we can't properly align anything there\n // because padding size is not known, and transport level should not be aware of MTProto structure\n encryptedData = encryptedData.subarray(0, encryptedData.byteLength - mod16)\n }\n\n const ige = createAesIgeForMessage(this._crypto, this.key, messageKey, false)\n const innerData = ige.decrypt(encryptedData)\n\n const msgKeySource = this._crypto.sha256(concatBuffers([this.serverSalt, innerData]))\n const expectedMessageKey = msgKeySource.subarray(8, 24)\n\n if (!buffersEqual(messageKey, expectedMessageKey)) {\n this.log.warn('received message with invalid messageKey = %h (expected %h)', messageKey, expectedMessageKey)\n\n return\n }\n\n const innerReader = new TlBinaryReader(this._readerMap, innerData)\n innerReader.seek(8) // skip salt\n const sessionId_ = innerReader.long()\n const messageId = innerReader.long(true)\n\n if (sessionId_.neq(sessionId)) {\n this.log.warn('ignoring message with invalid sessionId = %h', sessionId_)\n\n return\n }\n\n const seqNo = innerReader.uint()\n const length = innerReader.uint()\n\n if (length > innerData.length - 32 /* header size */) {\n this.log.warn('ignoring message with invalid length: %d > %d', length, innerData.length - 32)\n\n return\n }\n\n if (length % 4 !== 0) {\n this.log.warn('ignoring message with invalid length: %d is not a multiple of 4', length)\n\n return\n }\n\n const paddingSize = innerData.length - length - 32 // header size\n\n if (paddingSize < 12 || paddingSize > 1024) {\n this.log.warn('ignoring message with invalid padding size: %d', paddingSize)\n\n return\n }\n\n callback(messageId, seqNo, innerReader)\n }\n\n copyFrom(authKey: AuthKey): void {\n this.ready = authKey.ready\n this.key = authKey.key\n this.id = authKey.id\n this.serverSalt = authKey.serverSalt\n this.clientSalt = authKey.clientSalt\n }\n\n reset(): void {\n this.ready = false\n }\n}\n"]}
@@ -1,36 +1,38 @@
1
- import bigInt from 'big-integer';
2
1
  import Long from 'long';
3
2
  import { mtp } from '@mtcute/tl';
4
3
  import { TlBinaryReader, TlBinaryWriter, TlSerializationCounter } from '@mtcute/tl-runtime';
5
4
  import { MtArgumentError, MtSecurityError, MtTypeAssertionError } from '../types/index.js';
6
- import { buffersEqual, concatBuffers, dataViewFromBuffer, randomBytes } from '../utils/buffer-utils.js';
5
+ import { buffersEqual, concatBuffers, dataViewFromBuffer } from '../utils/buffer-utils.js';
7
6
  import { findKeyByFingerprints } from '../utils/crypto/keys.js';
8
7
  import { millerRabin } from '../utils/crypto/miller-rabin.js';
9
8
  import { generateKeyAndIvFromNonce } from '../utils/crypto/mtproto.js';
10
9
  import { xorBuffer, xorBufferInPlace } from '../utils/crypto/utils.js';
11
- import { bigIntToBuffer, bufferToBigInt } from '../utils/index.js';
10
+ import { bigIntModPow, bigIntToBuffer, bufferToBigInt } from '../utils/index.js';
12
11
  import { mtpAssertTypeIs } from '../utils/type-assertions.js';
13
12
  // Heavily based on code from https://github.com/LonamiWebs/Telethon/blob/master/telethon/network/authenticator.py
14
13
  // see https://core.telegram.org/mtproto/security_guidelines
15
- const DH_SAFETY_RANGE = bigInt[2].pow(2048 - 64);
16
- const KNOWN_DH_PRIME = bigInt('C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5B', 16);
17
- const TWO_POW_2047 = bigInt[2].pow(2047);
18
- const TWO_POW_2048 = bigInt[2].pow(2048);
14
+ // const DH_SAFETY_RANGE = bigInt[2].pow(2048 - 64)
15
+ const DH_SAFETY_RANGE = 2n ** (2048n - 64n);
16
+ const KNOWN_DH_PRIME =
17
+ // eslint-disable-next-line max-len
18
+ 0xc71caeb9c6b1c9048e6c522f70f13f73980d40238e3e21c14934d037563d930f48198a0aa7c14058229493d22530f4dbfa336f6e0ac925139543aed44cce7c3720fd51f69458705ac68cd4fe6b6b13abdc9746512969328454f18faf8c595f642477fe96bb2a941d5bcd1d4ac8cc49880708fa9b378e3c4f3a9060bee67cf9a4a4a695811051907e162753b56b0f6b410dba74d8a84b2a14b3144e0ef1284754fd17ed950d5965b4b9dd46582db1178d169c6bc465b0d6ff9ca3928fef5b9ae4e418fc15e83ebea0f87fa9ff5eed70050ded2849f47bf959d956850ce929851f0d8115f635b105ee2e4e15d04b2454bf6f4fadf034b10403119cd8e3b92fcc5bn;
19
+ const TWO_POW_2047 = 2n ** 2047n;
20
+ const TWO_POW_2048 = 2n ** 2048n;
19
21
  const checkedPrimesCache = [];
20
- function checkDhPrime(log, dhPrime, g) {
21
- if (KNOWN_DH_PRIME.eq(dhPrime)) {
22
+ function checkDhPrime(crypto, log, dhPrime, g) {
23
+ if (KNOWN_DH_PRIME === dhPrime) {
22
24
  log.debug('server is using known dh prime, skipping validation');
23
25
  return;
24
26
  }
25
- let checkedPrime = checkedPrimesCache.find((x) => x.prime.eq(dhPrime));
27
+ let checkedPrime = checkedPrimesCache.find((x) => x.prime === dhPrime);
26
28
  if (!checkedPrime) {
27
- if (dhPrime.lesserOrEquals(TWO_POW_2047) || dhPrime.greaterOrEquals(TWO_POW_2048)) {
29
+ if (dhPrime <= TWO_POW_2047 || dhPrime >= TWO_POW_2048) {
28
30
  throw new MtSecurityError('Step 3: dh_prime is not in the 2048-bit range');
29
31
  }
30
- if (!millerRabin(dhPrime)) {
32
+ if (!millerRabin(crypto, dhPrime)) {
31
33
  throw new MtSecurityError('Step 3: dh_prime is not prime');
32
34
  }
33
- if (!millerRabin(dhPrime.minus(1).divide(2))) {
35
+ if (!millerRabin(crypto, (dhPrime - 1n) / 2n)) {
34
36
  throw new MtSecurityError('Step 3: dh_prime is not a safe prime - (dh_prime-1)/2 is not prime');
35
37
  }
36
38
  log.debug('dh_prime is probably prime');
@@ -50,34 +52,34 @@ function checkDhPrime(log, dhPrime, g) {
50
52
  }
51
53
  switch (g) {
52
54
  case 2:
53
- if (dhPrime.mod(8).notEquals(7)) {
55
+ if (dhPrime % 8n !== 7n) {
54
56
  throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 8 != 7');
55
57
  }
56
58
  break;
57
59
  case 3:
58
- if (dhPrime.mod(3).notEquals(2)) {
60
+ if (dhPrime % 3n !== 2n) {
59
61
  throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 3 != 2');
60
62
  }
61
63
  break;
62
64
  case 4:
63
65
  break;
64
66
  case 5: {
65
- const mod = dhPrime.mod(5);
66
- if (mod.notEquals(1) && mod.notEquals(4)) {
67
+ const mod = dhPrime % 5n;
68
+ if (mod !== 1n && mod !== 4n) {
67
69
  throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 5 != 1 && dh_prime mod 5 != 4');
68
70
  }
69
71
  break;
70
72
  }
71
73
  case 6: {
72
- const mod = dhPrime.mod(24);
73
- if (mod.notEquals(19) && mod.notEquals(23)) {
74
+ const mod = dhPrime % 24n;
75
+ if (mod !== 19n && mod !== 23n) {
74
76
  throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 24 != 19 && dh_prime mod 24 != 23');
75
77
  }
76
78
  break;
77
79
  }
78
80
  case 7: {
79
- const mod = dhPrime.mod(7);
80
- if (mod.notEquals(3) && mod.notEquals(5) && mod.notEquals(6)) {
81
+ const mod = dhPrime % 7n;
82
+ if (mod !== 3n && mod !== 5n && mod !== 6n) {
81
83
  throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 7 != 3 && dh_prime mod 7 != 5 && dh_prime mod 7 != 6');
82
84
  }
83
85
  break;
@@ -88,41 +90,44 @@ function checkDhPrime(log, dhPrime, g) {
88
90
  checkedPrime.generators.push(g);
89
91
  log.debug('g = %d is safe to use with dh_prime', g);
90
92
  }
91
- async function rsaPad(data, crypto, key) {
93
+ function rsaPad(data, crypto, key) {
92
94
  // since Summer 2021, they use "version of RSA with a variant of OAEP+ padding explained below"
93
- const keyModulus = bigInt(key.modulus, 16);
94
- const keyExponent = bigInt(key.exponent, 16);
95
+ const keyModulus = BigInt(`0x${key.modulus}`);
96
+ const keyExponent = BigInt(`0x${key.exponent}`);
95
97
  if (data.length > 144) {
96
98
  throw new MtArgumentError('Failed to pad: too big data');
97
99
  }
98
- data = concatBuffers([data, randomBytes(192 - data.length)]);
100
+ const dataPadded = new Uint8Array(192);
101
+ dataPadded.set(data, 0);
102
+ crypto.randomFill(dataPadded.subarray(data.length));
103
+ data = dataPadded;
99
104
  for (;;) {
100
105
  const aesIv = new Uint8Array(32);
101
- const aesKey = randomBytes(32);
102
- const dataWithHash = concatBuffers([data, await crypto.sha256(concatBuffers([aesKey, data]))]);
106
+ const aesKey = crypto.randomBytes(32);
107
+ const dataWithHash = concatBuffers([data, crypto.sha256(concatBuffers([aesKey, data]))]);
103
108
  // we only need to reverse the data
104
109
  dataWithHash.subarray(0, 192).reverse();
105
- const aes = await crypto.createAesIge(aesKey, aesIv);
106
- const encrypted = await aes.encrypt(dataWithHash);
107
- const encryptedHash = await crypto.sha256(encrypted);
110
+ const aes = crypto.createAesIge(aesKey, aesIv);
111
+ const encrypted = aes.encrypt(dataWithHash);
112
+ const encryptedHash = crypto.sha256(encrypted);
108
113
  xorBufferInPlace(aesKey, encryptedHash);
109
114
  const decryptedData = concatBuffers([aesKey, encrypted]);
110
115
  const decryptedDataBigint = bufferToBigInt(decryptedData);
111
- if (decryptedDataBigint.geq(keyModulus)) {
116
+ if (decryptedDataBigint >= keyModulus) {
112
117
  continue;
113
118
  }
114
- const encryptedBigint = decryptedDataBigint.modPow(keyExponent, keyModulus);
119
+ const encryptedBigint = bigIntModPow(decryptedDataBigint, keyExponent, keyModulus);
115
120
  return bigIntToBuffer(encryptedBigint, 256);
116
121
  }
117
122
  }
118
- async function rsaEncrypt(data, crypto, key) {
123
+ function rsaEncrypt(data, crypto, key) {
119
124
  const toEncrypt = concatBuffers([
120
- await crypto.sha1(data),
125
+ crypto.sha1(data),
121
126
  data,
122
127
  // sha1 is always 20 bytes, so we're left with 255 - 20 - x padding
123
- randomBytes(235 - data.length),
128
+ crypto.randomBytes(235 - data.length),
124
129
  ]);
125
- const encryptedBigInt = bufferToBigInt(toEncrypt).modPow(bigInt(key.exponent, 16), bigInt(key.modulus, 16));
130
+ const encryptedBigInt = bigIntModPow(bufferToBigInt(toEncrypt), BigInt(`0x${key.exponent}`), BigInt(`0x${key.modulus}`));
126
131
  return bigIntToBuffer(encryptedBigInt);
127
132
  }
128
133
  /**
@@ -154,7 +159,7 @@ export async function doAuthorization(connection, crypto, expiresIn) {
154
159
  }
155
160
  if (expiresIn)
156
161
  log.prefix = '[PFS] ';
157
- const nonce = randomBytes(16);
162
+ const nonce = crypto.randomBytes(16);
158
163
  // Step 1: PQ request
159
164
  log.debug('starting PQ handshake (temp = %b), nonce = %h', expiresIn, nonce);
160
165
  await sendPlainMessage({ _: 'mt_req_pq_multi', nonce });
@@ -173,7 +178,7 @@ export async function doAuthorization(connection, crypto, expiresIn) {
173
178
  log.debug('found server key, fp = %s, old = %s', publicKey.fingerprint, publicKey.old);
174
179
  const [p, q] = await crypto.factorizePQ(resPq.pq);
175
180
  log.debug('factorized PQ: PQ = %h, P = %h, Q = %h', resPq.pq, p, q);
176
- const newNonce = randomBytes(32);
181
+ const newNonce = crypto.randomBytes(32);
177
182
  let dcId = connection.params.dc.id;
178
183
  if (connection.params.testMode)
179
184
  dcId += 10000;
@@ -192,8 +197,8 @@ export async function doAuthorization(connection, crypto, expiresIn) {
192
197
  };
193
198
  const pqInnerData = TlBinaryWriter.serializeObject(writerMap, _pqInnerData);
194
199
  const encryptedData = publicKey.old ?
195
- await rsaEncrypt(pqInnerData, crypto, publicKey) :
196
- await rsaPad(pqInnerData, crypto, publicKey);
200
+ rsaEncrypt(pqInnerData, crypto, publicKey) :
201
+ rsaPad(pqInnerData, crypto, publicKey);
197
202
  log.debug('requesting DH params');
198
203
  await sendPlainMessage({
199
204
  _: 'mt_req_DH_params',
@@ -217,13 +222,13 @@ export async function doAuthorization(connection, crypto, expiresIn) {
217
222
  throw new MtSecurityError('Step 2: AES block size is invalid');
218
223
  }
219
224
  // Step 3: complete DH exchange
220
- const [key, iv] = await generateKeyAndIvFromNonce(crypto, resPq.serverNonce, newNonce);
221
- const ige = await crypto.createAesIge(key, iv);
222
- const plainTextAnswer = await ige.decrypt(serverDhParams.encryptedAnswer);
225
+ const [key, iv] = generateKeyAndIvFromNonce(crypto, resPq.serverNonce, newNonce);
226
+ const ige = crypto.createAesIge(key, iv);
227
+ const plainTextAnswer = ige.decrypt(serverDhParams.encryptedAnswer);
223
228
  const innerDataHash = plainTextAnswer.subarray(0, 20);
224
229
  const serverDhInnerReader = new TlBinaryReader(readerMap, plainTextAnswer, 20);
225
230
  const serverDhInner = serverDhInnerReader.object();
226
- if (!buffersEqual(innerDataHash, await crypto.sha1(plainTextAnswer.subarray(20, serverDhInnerReader.pos)))) {
231
+ if (!buffersEqual(innerDataHash, crypto.sha1(plainTextAnswer.subarray(20, serverDhInnerReader.pos)))) {
227
232
  throw new MtSecurityError('Step 3: invalid inner data hash');
228
233
  }
229
234
  mtpAssertTypeIs('auth step 3', serverDhInner, 'mt_server_DH_inner_data');
@@ -235,30 +240,30 @@ export async function doAuthorization(connection, crypto, expiresIn) {
235
240
  }
236
241
  const dhPrime = bufferToBigInt(serverDhInner.dhPrime);
237
242
  const timeOffset = Math.floor(Date.now() / 1000) - serverDhInner.serverTime;
238
- const g = bigInt(serverDhInner.g);
243
+ const g = BigInt(serverDhInner.g);
239
244
  const gA = bufferToBigInt(serverDhInner.gA);
240
- checkDhPrime(log, dhPrime, serverDhInner.g);
245
+ checkDhPrime(crypto, log, dhPrime, serverDhInner.g);
241
246
  let retryId = Long.ZERO;
242
247
  const serverSalt = xorBuffer(newNonce.subarray(0, 8), resPq.serverNonce.subarray(0, 8));
243
248
  for (;;) {
244
- const b = bufferToBigInt(randomBytes(256));
245
- const gB = g.modPow(b, dhPrime);
246
- const authKey = bigIntToBuffer(gA.modPow(b, dhPrime));
247
- const authKeyAuxHash = (await crypto.sha1(authKey)).subarray(0, 8);
249
+ const b = bufferToBigInt(crypto.randomBytes(256));
250
+ const gB = bigIntModPow(g, b, dhPrime);
251
+ const authKey = bigIntToBuffer(bigIntModPow(gA, b, dhPrime));
252
+ const authKeyAuxHash = crypto.sha1(authKey).subarray(0, 8);
248
253
  // validate DH params
249
- if (g.lesserOrEquals(1) || g.greaterOrEquals(dhPrime.minus(bigInt.one))) {
254
+ if (g <= 1 || g >= dhPrime - 1n) {
250
255
  throw new MtSecurityError('g is not within (1, dh_prime - 1)');
251
256
  }
252
- if (gA.lesserOrEquals(1) || gA.greaterOrEquals(dhPrime.minus(bigInt.one))) {
257
+ if (gA <= 1 || gA >= dhPrime - 1n) {
253
258
  throw new MtSecurityError('g_a is not within (1, dh_prime - 1)');
254
259
  }
255
- if (gB.lesserOrEquals(1) || gB.greaterOrEquals(dhPrime.minus(bigInt.one))) {
260
+ if (gB <= 1 || gB >= dhPrime - 1n) {
256
261
  throw new MtSecurityError('g_b is not within (1, dh_prime - 1)');
257
262
  }
258
- if (gA.lt(DH_SAFETY_RANGE) || gA.gt(dhPrime.minus(DH_SAFETY_RANGE))) {
263
+ if (gA <= DH_SAFETY_RANGE || gA >= dhPrime - DH_SAFETY_RANGE) {
259
264
  throw new MtSecurityError('g_a is not within (2^{2048-64}, dh_prime - 2^{2048-64})');
260
265
  }
261
- if (gB.lt(DH_SAFETY_RANGE) || gB.gt(dhPrime.minus(DH_SAFETY_RANGE))) {
266
+ if (gB <= DH_SAFETY_RANGE || gB >= dhPrime - DH_SAFETY_RANGE) {
262
267
  throw new MtSecurityError('g_b is not within (2^{2048-64}, dh_prime - 2^{2048-64})');
263
268
  }
264
269
  const gB_ = bigIntToBuffer(gB, 0, false);
@@ -277,11 +282,11 @@ export async function doAuthorization(connection, crypto, expiresIn) {
277
282
  const clientDhInnerWriter = TlBinaryWriter.alloc(writerMap, innerLength);
278
283
  clientDhInnerWriter.pos = 20;
279
284
  clientDhInnerWriter.object(clientDhInner);
280
- const clientDhInnerHash = await crypto.sha1(clientDhInnerWriter.uint8View.subarray(20, clientDhInnerWriter.pos));
285
+ const clientDhInnerHash = crypto.sha1(clientDhInnerWriter.uint8View.subarray(20, clientDhInnerWriter.pos));
281
286
  clientDhInnerWriter.pos = 0;
282
287
  clientDhInnerWriter.raw(clientDhInnerHash);
283
288
  log.debug('sending client DH (timeOffset = %d)', timeOffset);
284
- const clientDhEncrypted = await ige.encrypt(clientDhInnerWriter.uint8View);
289
+ const clientDhEncrypted = ige.encrypt(clientDhInnerWriter.uint8View);
285
290
  await sendPlainMessage({
286
291
  _: 'mt_set_client_DH_params',
287
292
  nonce,
@@ -304,7 +309,7 @@ export async function doAuthorization(connection, crypto, expiresIn) {
304
309
  throw new MtTypeAssertionError('auth step 4', '!mt_dh_gen_fail', dhGen._);
305
310
  }
306
311
  if (dhGen._ === 'mt_dh_gen_retry') {
307
- const expectedHash = await crypto.sha1(concatBuffers([newNonce, new Uint8Array([2]), authKeyAuxHash]));
312
+ const expectedHash = crypto.sha1(concatBuffers([newNonce, new Uint8Array([2]), authKeyAuxHash]));
308
313
  if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash2)) {
309
314
  throw Error('Step 4: invalid retry nonce hash from server');
310
315
  }
@@ -313,7 +318,7 @@ export async function doAuthorization(connection, crypto, expiresIn) {
313
318
  }
314
319
  if (dhGen._ !== 'mt_dh_gen_ok')
315
320
  throw new Error(); // unreachable
316
- const expectedHash = await crypto.sha1(concatBuffers([newNonce, new Uint8Array([1]), authKeyAuxHash]));
321
+ const expectedHash = crypto.sha1(concatBuffers([newNonce, new Uint8Array([1]), authKeyAuxHash]));
317
322
  if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash1)) {
318
323
  throw Error('Step 4: invalid nonce hash from server');
319
324
  }