From b36ec8cf444aed3fed3c83e7cdd5928789f655f9 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 21 May 2021 14:50:12 +0300 Subject: [PATCH] GramJs: Fix ESLint errors (#1070) --- src/lib/gramjs/.eslintrc | 6 +- src/lib/gramjs/Helpers.js | 2 +- src/lib/gramjs/Password.js | 3 +- src/lib/gramjs/Utils.js | 30 ++--- src/lib/gramjs/client/2fa.ts | 4 +- src/lib/gramjs/client/TelegramClient.js | 118 ++++++++---------- src/lib/gramjs/client/auth.ts | 13 +- src/lib/gramjs/client/downloadFile.ts | 66 +++++----- src/lib/gramjs/client/uploadFile.ts | 7 +- src/lib/gramjs/crypto/AuthKey.js | 5 +- src/lib/gramjs/crypto/Factorizator.js | 1 + src/lib/gramjs/crypto/IGE.js | 4 +- src/lib/gramjs/crypto/RSA.js | 2 +- src/lib/gramjs/crypto/crypto.js | 6 +- src/lib/gramjs/errors/Common.js | 5 +- src/lib/gramjs/errors/RPCBaseErrors.js | 2 +- src/lib/gramjs/errors/RPCErrorList.js | 9 ++ src/lib/gramjs/errors/index.js | 12 +- src/lib/gramjs/events/Raw.js | 6 +- src/lib/gramjs/events/common.js | 14 +-- src/lib/gramjs/extensions/BinaryReader.js | 4 +- src/lib/gramjs/extensions/Logger.js | 6 +- src/lib/gramjs/extensions/MessagePacker.js | 10 +- .../gramjs/extensions/PromisedWebSockets.js | 8 +- src/lib/gramjs/network/Authenticator.js | 11 +- src/lib/gramjs/network/MTProtoPlainSender.js | 1 - src/lib/gramjs/network/MTProtoSender.js | 72 ++++++----- src/lib/gramjs/network/MTProtoState.js | 9 +- src/lib/gramjs/network/RequestState.js | 8 +- .../gramjs/network/connection/Connection.js | 32 ++--- .../gramjs/network/connection/TCPAbridged.js | 2 +- .../network/connection/TCPObfuscated.js | 2 +- src/lib/gramjs/sessions/Abstract.js | 5 +- src/lib/gramjs/sessions/CacheApiSession.js | 3 +- src/lib/gramjs/sessions/IdbSession.js | 6 +- .../gramjs/sessions/LocalStorageSession.js | 6 +- src/lib/gramjs/sessions/Memory.js | 8 +- src/lib/gramjs/sessions/StorageSession.js | 15 ++- src/lib/gramjs/sessions/StringSession.js | 4 +- src/lib/gramjs/tl/MTProtoRequest.js | 4 + src/lib/gramjs/tl/api.js | 28 +++-- src/lib/gramjs/tl/core/GZIPPacked.js | 4 +- src/lib/gramjs/tl/core/MessageContainer.js | 6 +- src/lib/gramjs/tl/core/RPCResult.js | 4 +- src/lib/gramjs/tl/generationHelpers.js | 50 ++++---- src/lib/gramjs/tl/index.js | 3 - 46 files changed, 330 insertions(+), 296 deletions(-) diff --git a/src/lib/gramjs/.eslintrc b/src/lib/gramjs/.eslintrc index 20ca23d80..04f6b8c80 100644 --- a/src/lib/gramjs/.eslintrc +++ b/src/lib/gramjs/.eslintrc @@ -20,6 +20,10 @@ ], "no-bitwise": "off", "no-underscore-dangle": "off", - "no-null/no-null": "off" + "no-continue": "off", + "no-restricted-syntax": "off", + "class-methods-use-this": "off", + "max-classes-per-file": "off", + "camelcase": "error" } } diff --git a/src/lib/gramjs/Helpers.js b/src/lib/gramjs/Helpers.js index 0c4bf80c9..59a71a969 100644 --- a/src/lib/gramjs/Helpers.js +++ b/src/lib/gramjs/Helpers.js @@ -310,7 +310,7 @@ function makeCRCTable() { return crcTable; } -let crcTable = null; +let crcTable; function crc32(buf) { if (!crcTable) { diff --git a/src/lib/gramjs/Password.js b/src/lib/gramjs/Password.js index 7633f06f6..36e97ed2c 100644 --- a/src/lib/gramjs/Password.js +++ b/src/lib/gramjs/Password.js @@ -1,5 +1,4 @@ const BigInt = require('big-integer'); -const Factorizator = require('./crypto/Factorizator'); const { constructors } = require('./tl'); const { readBigIntFromBuffer, @@ -148,7 +147,7 @@ function xor(a, b) { const length = Math.min(a.length, b.length); for (let i = 0; i < length; i++) { - a[i] = a[i] ^ b[i]; + a[i] ^= b[i]; } return a; diff --git a/src/lib/gramjs/Utils.js b/src/lib/gramjs/Utils.js index 369ee7bc9..ff46185ae 100644 --- a/src/lib/gramjs/Utils.js +++ b/src/lib/gramjs/Utils.js @@ -1,16 +1,9 @@ const { constructors } = require('./tl'); -const USERNAME_RE = new RegExp('@|(?:https?:\\/\\/)?(?:www\\.)?' - + '(?:telegram\\.(?:me|dog)|t\\.me)\\/(@|joinchat\\/)?'); - +// eslint-disable-next-line max-len const JPEG_HEADER = Buffer.from('ffd8ffe000104a46494600010100000100010000ffdb004300281c1e231e19282321232d2b28303c64413c37373c7b585d4964918099968f808c8aa0b4e6c3a0aadaad8a8cc8ffcbdaeef5ffffff9bc1fffffffaffe6fdfff8ffdb0043012b2d2d3c353c76414176f8a58ca5f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8ffc00011080000000003012200021101031101ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00', 'hex'); const JPEG_FOOTER = Buffer.from('ffd9', 'hex'); -const TG_JOIN_RE = new RegExp('tg:\\/\\/(join)\\?invite='); - -const VALID_USERNAME_RE = new RegExp('^([a-z]((?!__)[\\w\\d]){3,30}[a-z\\d]|gif|vid|' - + 'pic|bing|wiki|imdb|bold|vote|like|coub)$'); - function _raiseCastFail(entity, target) { throw new Error(`Cannot cast ${entity.className} to any kind of ${target}`); } @@ -111,6 +104,7 @@ function getInputPeer(entity, allowSelf = true, checkHash = true) { } _raiseCastFail(entity, 'InputPeer'); + return undefined; } /** @@ -252,7 +246,8 @@ function getInputMessage(message) { /** * Adds the JPG header and footer to a stripped image. - * Ported from https://github.com/telegramdesktop/tdesktop/blob/bec39d89e19670eb436dc794a8f20b657cb87c71/Telegram/SourceFiles/ui/image/image.cpp#L225 + * Ported from https://github.com/telegramdesktop/ + * tdesktop/blob/bec39d89e19670eb436dc794a8f20b657cb87c71/Telegram/SourceFiles/ui/image/image.cpp#L225 * @param stripped{Buffer} * @returns {Buffer} @@ -263,7 +258,9 @@ function strippedPhotoToJpg(stripped) { return stripped; } const header = Buffer.from(JPEG_HEADER); + // eslint-disable-next-line prefer-destructuring header[164] = stripped[1]; + // eslint-disable-next-line prefer-destructuring header[166] = stripped[2]; return Buffer.concat([header, stripped.slice(3), JPEG_FOOTER]); } @@ -502,8 +499,8 @@ function _getEntityPair(entityId, entities, cache, getInputPeer = getInputPeer) */ function getMessageId(message) { - if (message === null || message === undefined) { - return null; + if (message === undefined) { + return undefined; } if (typeof message === 'number') { return message; @@ -515,15 +512,6 @@ function getMessageId(message) { } -/** - * Parses the given phone, or returns `None` if it's invalid. - * @param phone - */ -function parsePhone(phone) { - return phone.toString() - .replace(/[+()\s-]/gm, ''); -} - /** Parses the given username or channel access hash, given a string, username or URL. Returns a tuple consisting of @@ -617,7 +605,7 @@ function isListLike(item) { ) } */ -function getDC(dcId, cdn = false) { +function getDC(dcId) { switch (dcId) { case 1: return { diff --git a/src/lib/gramjs/client/2fa.ts b/src/lib/gramjs/client/2fa.ts index 52a9c5fde..7d4c30e29 100644 --- a/src/lib/gramjs/client/2fa.ts +++ b/src/lib/gramjs/client/2fa.ts @@ -1,4 +1,5 @@ import TelegramClient from './TelegramClient'; +// eslint-disable-next-line import/no-named-default import { default as Api } from '../tl/api'; import { generateRandomBytes } from '../Helpers'; import { computeCheck, computeDigest } from '../Password'; @@ -100,7 +101,8 @@ export async function updateTwoFaSettings( })); } catch (e) { if (e instanceof errors.EmailUnconfirmedError) { - while (1) { + // eslint-disable-next-line no-constant-condition + while (true) { try { const code = await emailCodeCallback!(e.codeLength); diff --git a/src/lib/gramjs/client/TelegramClient.js b/src/lib/gramjs/client/TelegramClient.js index 4f4c11d99..7ecc2e5f3 100644 --- a/src/lib/gramjs/client/TelegramClient.js +++ b/src/lib/gramjs/client/TelegramClient.js @@ -4,7 +4,6 @@ const { sleep } = require('../Helpers'); const errors = require('../errors'); const MemorySession = require('../sessions/Memory'); const Helpers = require('../Helpers'); -const { BinaryWriter } = require('../extensions'); const utils = require('../Utils'); const Session = require('../sessions/Abstract'); const { LAYER } = require('../tl/AllTLObjects'); @@ -13,7 +12,6 @@ const { requests, } = require('../tl'); const MTProtoSender = require('../network/MTProtoSender'); -const { UpdateConnectionState } = require('../network'); const { ConnectionTCPObfuscated } = require('../network/connection/TCPObfuscated'); const { authFlow, @@ -35,7 +33,7 @@ class TelegramClient { static DEFAULT_OPTIONS = { connection: ConnectionTCPObfuscated, useIPV6: false, - proxy: null, + proxy: undefined, timeout: 10, requestRetries: 5, connectionRetries: Infinity, @@ -43,9 +41,9 @@ class TelegramClient { autoReconnect: true, sequentialUpdates: false, floodSleepLimit: 60, - deviceModel: null, - systemVersion: null, - appVersion: null, + deviceModel: undefined, + systemVersion: undefined, + appVersion: undefined, langCode: 'en', systemLangCode: 'en', baseLogger: 'gramjs', @@ -91,7 +89,7 @@ class TelegramClient { this._phoneCodeHash = {}; this.session = session; // this._entityCache = EntityCache(); - this.apiId = parseInt(apiId); + this.apiId = parseInt(apiId, 10); this.apiHash = apiHash; this._requestRetries = args.requestRetries; @@ -123,14 +121,14 @@ class TelegramClient { langPack: '', // this should be left empty. systemLangCode: args.systemLangCode, query: x, - proxy: null, // no proxies yet. + proxy: undefined, // no proxies yet. }), }); }; this._args = args; // These will be set later - this._config = null; + this._config = undefined; this.phoneCodeHashes = []; this._borrowedSenderPromises = {}; this._additionalDcsDisabled = args.additionalDcsDisabled; @@ -178,7 +176,8 @@ class TelegramClient { await this.session.load(); if (!this.session.serverAddress || (this.session.serverAddress.includes(':') !== this._useIPV6)) { - this.session.setDC(DEFAULT_DC_ID, this._useIPV6 ? DEFAULT_IPV6_IP : DEFAULT_IPV4_IP, this._args.useWSS ? 443 : 80); + this.session.setDC(DEFAULT_DC_ID, this._useIPV6 + ? DEFAULT_IPV6_IP : DEFAULT_IPV4_IP, this._args.useWSS ? 443 : 80); } } @@ -208,7 +207,7 @@ class TelegramClient { try { await this.invoke(new requests.updates.GetState()); } catch (e) { - + // we don't care about errors here } } } @@ -230,6 +229,7 @@ class TelegramClient { if (sender) { return sender.disconnect(); } + return undefined; }); }), ); @@ -253,13 +253,13 @@ class TelegramClient { this.session.setDC(newDc, DC.ipAddress, DC.port); // authKey's are associated with a server, which has now changed // so it's not valid anymore. Set to None to force recreating it. - await this._sender.authKey.setKey(null); - this.session.setAuthKey(null); + await this._sender.authKey.setKey(undefined); + this.session.setAuthKey(undefined); await this.disconnect(); return this.connect(); } - async _authKeyCallback(authKey, dcId) { + _authKeyCallback(authKey, dcId) { this.session.setAuthKey(authKey, dcId); } @@ -270,7 +270,7 @@ class TelegramClient { delete this._borrowedSenderPromises[dcId]; } - async _borrowExportedSender(dcId) { + _borrowExportedSender(dcId) { if (this._additionalDcsDisabled) { return undefined; } @@ -326,7 +326,7 @@ class TelegramClient { await sender.disconnect(); } } - return null; + return undefined; } // end region @@ -345,18 +345,15 @@ class TelegramClient { * @param [args[workers] {number}] * @returns {Promise} */ - async downloadFile(inputLocation, args = {}) { + downloadFile(inputLocation, args = {}) { return downloadFile(this, inputLocation, args); } - async downloadMedia(messageOrMedia, args) { - let date; + downloadMedia(messageOrMedia, args) { let media; if (messageOrMedia instanceof constructors.Message) { - date = messageOrMedia.date; media = messageOrMedia.media; } else { - date = new Date().getTime(); media = messageOrMedia; } if (typeof media === 'string') { @@ -377,9 +374,10 @@ class TelegramClient { } else if (media instanceof constructors.WebDocument || media instanceof constructors.WebDocumentNoProxy) { return this._downloadWebDocument(media, args); } + return undefined; } - async downloadProfilePhoto(entity, isBig = false) { + downloadProfilePhoto(entity, isBig = false) { // ('User', 'Chat', 'UserFull', 'ChatFull') const ENTITIES = [0x2da17977, 0xc5af5d94, 0x1f4661b9, 0xd49a2697]; // ('InputPeer', 'InputUser', 'InputChannel') @@ -393,7 +391,7 @@ class TelegramClient { if (!entity.photo) { // Special case: may be a ChatFull with photo:Photo if (!entity.chatPhoto) { - return null; + return undefined; } return this._downloadPhoto( @@ -417,32 +415,14 @@ class TelegramClient { // as input location, because then this method would be able // to "download the profile photo of a message", i.e. its // media which should be done with `download_media` instead. - return null; - } - try { - return this.downloadFile(loc, { - dcId, - }); - } catch (e) { - // TODO this should never raise - throw e; - /* if (e.message === 'LOCATION_INVALID') { - const ie = await this.getInputEntity(entity) - if (ie instanceof constructors.InputPeerChannel) { - const full = await this.invoke(new requests.channels.GetFullChannel({ - channel: ie, - })) - return this._downloadPhoto(full.fullChat.chatPhoto, { sizeType }) - } else { - return null - } - } else { - throw e - } */ + return undefined; } + return this.downloadFile(loc, { + dcId, + }); } - async downloadStickerSetThumb(stickerSet) { + downloadStickerSetThumb(stickerSet) { if (!stickerSet.thumbs || !stickerSet.thumbs.length) { return undefined; } @@ -462,7 +442,7 @@ class TelegramClient { _pickFileSize(sizes, sizeType) { if (!sizeType || !sizes || !sizes.length) { - return null; + return undefined; } const indexOfSize = sizeTypes.indexOf(sizeType); let size; @@ -472,7 +452,7 @@ class TelegramClient { return size; } } - return null; + return undefined; } @@ -487,16 +467,16 @@ class TelegramClient { return data; } - async _downloadPhoto(photo, args) { + _downloadPhoto(photo, args) { if (photo instanceof constructors.MessageMediaPhoto) { photo = photo.photo; } if (!(photo instanceof constructors.Photo)) { - return; + return undefined; } const size = this._pickFileSize(photo.sizes, args.sizeType); if (!size || (size instanceof constructors.PhotoSizeEmpty)) { - return; + return undefined; } if (size instanceof constructors.PhotoCachedSize || size instanceof constructors.PhotoStrippedSize) { @@ -517,22 +497,23 @@ class TelegramClient { ); } - async _downloadDocument(doc, args) { + _downloadDocument(doc, args) { if (doc instanceof constructors.MessageMediaDocument) { doc = doc.document; } if (!(doc instanceof constructors.Document)) { - return; + return undefined; } - let size = null; + let size; if (args.sizeType) { - size = doc.thumbs ? this._pickFileSize(doc.thumbs, args.sizeType) : null; + size = doc.thumbs ? this._pickFileSize(doc.thumbs, args.sizeType) : undefined; if (!size && doc.mimeType.startsWith('video/')) { - return; + return undefined; } - if (size && (size instanceof constructors.PhotoCachedSize || size instanceof constructors.PhotoStrippedSize)) { + if (size && (size instanceof constructors.PhotoCachedSize + || size instanceof constructors.PhotoStrippedSize)) { return this._downloadCachedPhotoSize(size); } } @@ -555,10 +536,12 @@ class TelegramClient { ); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars _downloadContact(media, args) { throw new Error('not implemented'); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars _downloadWebDocument(media, args) { throw new Error('not implemented'); } @@ -601,7 +584,8 @@ class TelegramClient { } else if (e instanceof errors.PhoneMigrateError || e instanceof errors.NetworkMigrateError || e instanceof errors.UserMigrateError) { this._log.info(`Phone migrated to ${e.newDc}`); - const shouldRaise = e instanceof errors.PhoneMigrateError || e instanceof errors.NetworkMigrateError; + const shouldRaise = e instanceof errors.PhoneMigrateError + || e instanceof errors.NetworkMigrateError; if (shouldRaise && await checkAuthorization(this)) { throw e; } @@ -619,7 +603,10 @@ class TelegramClient { return (await this.invoke(new requests.users .GetUsers({ id: [new constructors.InputUserSelf()] })))[0]; } catch (e) { + this._log.warn('error while getting me'); + this._log.warn(e); } + return undefined; } async start(authParams) { @@ -666,9 +653,9 @@ class TelegramClient { this._processUpdate(u, update.updates, entities); } } else if (update instanceof constructors.UpdateShort) { - this._processUpdate(update.update, null); + this._processUpdate(update.update, undefined); } else { - this._processUpdate(update, null); + this._processUpdate(update, undefined); } // TODO add caching // this._stateCache.update(update) @@ -915,10 +902,10 @@ class TelegramClient { } */ async _dispatchUpdate(args = { - update: null, - others: null, - channelId: null, - ptsDate: null, + update: undefined, + others: undefined, + channelId: undefined, + ptsDate: undefined, }) { for (const [builder, callback] of this._eventBuilders) { const event = builder.build(args.update); @@ -938,7 +925,7 @@ class TelegramClient { } } -async function timeout(promise, ms) { +function timeout(promise, ms) { return Promise.race([ promise, Helpers.sleep(ms) @@ -959,6 +946,7 @@ async function attempts(cb, times, pause) { await Helpers.sleep(pause); } } + return undefined; } module.exports = TelegramClient; diff --git a/src/lib/gramjs/client/auth.ts b/src/lib/gramjs/client/auth.ts index 33000fe40..30546ca41 100644 --- a/src/lib/gramjs/client/auth.ts +++ b/src/lib/gramjs/client/auth.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-named-default import { default as Api } from '../tl/api'; import TelegramClient from './TelegramClient'; import utils from '../Utils'; @@ -55,7 +56,8 @@ async function signInUser( let phoneCodeHash; let isCodeViaApp = false; - while (1) { + // eslint-disable-next-line no-constant-condition + while (true) { try { if (typeof authParams.phoneNumber === 'function') { try { @@ -92,6 +94,7 @@ async function signInUser( let isRegistrationRequired = false; let termsOfService; + // eslint-disable-next-line no-constant-condition while (1) { try { try { @@ -132,6 +135,7 @@ async function signInUser( } if (isRegistrationRequired) { + // eslint-disable-next-line no-constant-condition while (1) { try { const [firstName, lastName] = await authParams.firstAndLastNames(); @@ -168,6 +172,7 @@ async function signInUserWithQrCode( let isScanningComplete = false; const inputPromise = (async () => { + // eslint-disable-next-line no-constant-condition while (1) { if (isScanningComplete) { break; @@ -228,7 +233,8 @@ async function signInUserWithQrCode( token: result2.token, })); - if (migratedResult instanceof Api.auth.LoginTokenSuccess && migratedResult.authorization instanceof Api.auth.Authorization) { + if (migratedResult instanceof Api.auth.LoginTokenSuccess + && migratedResult.authorization instanceof Api.auth.Authorization) { return migratedResult.authorization.user; } } @@ -241,6 +247,7 @@ async function signInUserWithQrCode( } // This is a workaround for TypeScript (never actually reached) + // eslint-disable-next-line no-throw-literal throw undefined; } @@ -288,6 +295,7 @@ async function sendCode( async function signInWithPassword( client: TelegramClient, apiCredentials: ApiCredentials, authParams: UserAuthParams, ): Promise { + // eslint-disable-next-line no-constant-condition while (1) { try { const passwordSrpResult = await client.invoke(new Api.account.GetPassword()); @@ -307,6 +315,7 @@ async function signInWithPassword( } } + // eslint-disable-next-line no-unreachable return undefined!; // Never reached (TypeScript fix) } diff --git a/src/lib/gramjs/client/downloadFile.ts b/src/lib/gramjs/client/downloadFile.ts index 09343f1e6..e538765ea 100644 --- a/src/lib/gramjs/client/downloadFile.ts +++ b/src/lib/gramjs/client/downloadFile.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-named-default import { default as Api } from '../tl/api'; import TelegramClient from './TelegramClient'; import { getAppropriatedPartSize } from '../Utils'; @@ -34,13 +35,45 @@ const DEFAULT_CHUNK_SIZE = 64; // kb const ONE_MB = 1024 * 1024; const REQUEST_TIMEOUT = 15000; + +class Foreman { + private deferred: Deferred | undefined; + + private activeWorkers = 0; + + constructor(private maxWorkers: number) { + } + + requestWorker() { + this.activeWorkers++; + + if (this.activeWorkers > this.maxWorkers) { + this.deferred = createDeferred(); + return this.deferred.promise; + } + + return Promise.resolve(); + } + + releaseWorker() { + this.activeWorkers--; + + if (this.deferred && (this.activeWorkers <= this.maxWorkers)) { + this.deferred.resolve(); + } + } +} + export async function downloadFile( client: TelegramClient, inputLocation: Api.InputFileLocation, fileParams: DownloadFileParams, ) { let { - partSizeKb, fileSize, workers = 1, end, + partSizeKb, end, + } = fileParams; + const { + fileSize, workers = 1, } = fileParams; const { dcId, progressCallback, start = 0 } = fileParams; @@ -88,12 +121,13 @@ export async function downloadFile( progressCallback(progress); } + // eslint-disable-next-line no-constant-condition while (true) { let limit = partSize; let isPrecise = false; if (Math.floor(offset / ONE_MB) !== Math.floor((offset + limit - 1) / ONE_MB)) { - limit = ONE_MB - offset % ONE_MB; + limit = ONE_MB - (offset % ONE_MB); isPrecise = true; } @@ -104,6 +138,7 @@ export async function downloadFile( break; } + // eslint-disable-next-line no-loop-func promises.push((async () => { try { const result = await Promise.race([ @@ -151,33 +186,6 @@ export async function downloadFile( return Buffer.concat(buffers, totalLength); } -class Foreman { - private deferred: Deferred | undefined; - - private activeWorkers = 0; - - constructor(private maxWorkers: number) { - } - - requestWorker() { - this.activeWorkers++; - - if (this.activeWorkers > this.maxWorkers) { - this.deferred = createDeferred(); - return this.deferred.promise; - } - - return Promise.resolve(); - } - - releaseWorker() { - this.activeWorkers--; - - if (this.deferred && (this.activeWorkers <= this.maxWorkers)) { - this.deferred.resolve(); - } - } -} function createDeferred(): Deferred { let resolve: Deferred['resolve']; diff --git a/src/lib/gramjs/client/uploadFile.ts b/src/lib/gramjs/client/uploadFile.ts index e7f4f2c92..9844a85ed 100644 --- a/src/lib/gramjs/client/uploadFile.ts +++ b/src/lib/gramjs/client/uploadFile.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line import/no-named-default import { default as Api } from '../tl/api'; import TelegramClient from './TelegramClient'; @@ -61,6 +62,7 @@ export async function uploadFile( for (let j = i; j < end; j++) { const bytes = buffer.slice(j * partSize, (j + 1) * partSize); + // eslint-disable-next-line no-loop-func sendingParts.push((async () => { await sender.send( isLarge @@ -94,6 +96,7 @@ export async function uploadFile( ]); } catch (err) { if (err.message === 'TIMEOUT') { + // eslint-disable-next-line no-console console.warn('Upload timeout. Retrying...'); i -= workers; continue; @@ -117,10 +120,6 @@ export async function uploadFile( }); } -function generateRandomBigInt() { - return readBigIntFromBuffer(generateRandomBytes(8), false); -} - function fileToBuffer(file: File) { return new Response(file).arrayBuffer(); } diff --git a/src/lib/gramjs/crypto/AuthKey.js b/src/lib/gramjs/crypto/AuthKey.js index bd3ffaad0..85d346000 100644 --- a/src/lib/gramjs/crypto/AuthKey.js +++ b/src/lib/gramjs/crypto/AuthKey.js @@ -22,7 +22,10 @@ class AuthKey { async setKey(value) { if (!value) { - this._key = this.auxHash = this.keyId = this._hash = null; + this._key = undefined; + this.auxHash = undefined; + this.keyId = undefined; + this._hash = undefined; return; } if (value instanceof AuthKey) { diff --git a/src/lib/gramjs/crypto/Factorizator.js b/src/lib/gramjs/crypto/Factorizator.js index e8595acb7..98c8a1b8b 100644 --- a/src/lib/gramjs/crypto/Factorizator.js +++ b/src/lib/gramjs/crypto/Factorizator.js @@ -70,6 +70,7 @@ class Factorizator { if (g.eq(pq)) { + // eslint-disable-next-line no-constant-condition while (true) { ys = (modExp(ys, BigInt(2), pq)).add(c) .remainder(pq); diff --git a/src/lib/gramjs/crypto/IGE.js b/src/lib/gramjs/crypto/IGE.js index 0315081d7..deff7c511 100644 --- a/src/lib/gramjs/crypto/IGE.js +++ b/src/lib/gramjs/crypto/IGE.js @@ -1,10 +1,10 @@ -const { IGE: aes_ige } = require('@cryptography/aes'); +const { IGE: AESIGE } = require('@cryptography/aes'); const Helpers = require('../Helpers'); class IGENEW { constructor(key, iv) { - this.ige = new aes_ige(key, iv); + this.ige = new AESIGE(key, iv); } /** diff --git a/src/lib/gramjs/crypto/RSA.js b/src/lib/gramjs/crypto/RSA.js index 6230d1f3f..648c0ffde 100644 --- a/src/lib/gramjs/crypto/RSA.js +++ b/src/lib/gramjs/crypto/RSA.js @@ -1,8 +1,8 @@ +/* eslint-disable max-len */ const BigInt = require('big-integer'); const { readBigIntFromBuffer, readBufferFromBigInt, - getByteArray, sha1, generateRandomBytes, modExp, diff --git a/src/lib/gramjs/crypto/crypto.js b/src/lib/gramjs/crypto/crypto.js index ba5768dcc..aeae06e90 100644 --- a/src/lib/gramjs/crypto/crypto.js +++ b/src/lib/gramjs/crypto/crypto.js @@ -35,7 +35,7 @@ class CTR { this._counter = counter; - this._remainingCounter = null; + this._remainingCounter = undefined; this._remainingCounterIndex = 16; this._aes = new AES(getWords(key)); @@ -95,12 +95,16 @@ class Hash { this.data = new Uint8Array(data); } + async digest() { if (this.algorithm === 'sha1') { + // eslint-disable-next-line no-restricted-globals return Buffer.from(await self.crypto.subtle.digest('SHA-1', this.data)); } else if (this.algorithm === 'sha256') { + // eslint-disable-next-line no-restricted-globals return Buffer.from(await self.crypto.subtle.digest('SHA-256', this.data)); } + return undefined; } } diff --git a/src/lib/gramjs/errors/Common.js b/src/lib/gramjs/errors/Common.js index ef974f5e3..4971cb478 100644 --- a/src/lib/gramjs/errors/Common.js +++ b/src/lib/gramjs/errors/Common.js @@ -22,6 +22,7 @@ class TypeNotFoundError extends Error { read with ID ${invalidConstructorId}. Most likely, a TLObject was trying to be read when it should not be read. Remaining bytes: ${remaining.length}`); if (typeof alert !== 'undefined') { + // eslint-disable-next-line no-alert alert(`Missing MTProto Entity: Please, make sure to add TL definition for ID ${invalidConstructorId}`); } this.invalidConstructorId = invalidConstructorId; @@ -47,7 +48,7 @@ class InvalidChecksumError extends Error { */ class InvalidBufferError extends Error { constructor(payload) { - let code = null; + let code; if (payload.length === 4) { code = -payload.readInt32LE(0); super(`Invalid response buffer (HTTP code ${code})`); @@ -100,7 +101,7 @@ class BadMessageError extends Error { 'Incorrect two lower order msg_id bits (the server expects client message msg_id ' + 'to be divisible by 4).', - 19: 'Container msg_id is the same as msg_id of a previously received message ' + '(this must never happen).', + 19: 'Container msg_id is the same as msg_id of a previously received message (this must never happen).', 20: 'Message too old, and it cannot be verified whether the server has received a ' diff --git a/src/lib/gramjs/errors/RPCBaseErrors.js b/src/lib/gramjs/errors/RPCBaseErrors.js index faa7ac244..ef7edb440 100644 --- a/src/lib/gramjs/errors/RPCBaseErrors.js +++ b/src/lib/gramjs/errors/RPCBaseErrors.js @@ -2,7 +2,7 @@ * Base class for all Remote Procedure Call errors. */ class RPCError extends Error { - constructor(message, request, code = null) { + constructor(message, request, code = undefined) { super( 'RPCError {0}: {1}{2}' .replace('{0}', code) diff --git a/src/lib/gramjs/errors/RPCErrorList.js b/src/lib/gramjs/errors/RPCErrorList.js index e50dc403e..5d70ed419 100644 --- a/src/lib/gramjs/errors/RPCErrorList.js +++ b/src/lib/gramjs/errors/RPCErrorList.js @@ -9,7 +9,9 @@ const { class UserMigrateError extends InvalidDCError { constructor(args) { const newDc = Number(args.capture || 0); + // eslint-disable-next-line max-len super(`The user whose identity is being used to execute queries is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`); + // eslint-disable-next-line max-len this.message = `The user whose identity is being used to execute queries is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`; this.newDc = newDc; } @@ -19,7 +21,9 @@ class UserMigrateError extends InvalidDCError { class PhoneMigrateError extends InvalidDCError { constructor(args) { const newDc = Number(args.capture || 0); + // eslint-disable-next-line max-len super(`The phone number a user is trying to use for authorization is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`); + // eslint-disable-next-line max-len this.message = `The phone number a user is trying to use for authorization is associated with DC ${newDc}${RPCError._fmtRequest(args.request)}`; this.newDc = newDc; } @@ -28,7 +32,9 @@ class PhoneMigrateError extends InvalidDCError { class SlowModeWaitError extends FloodError { constructor(args) { const seconds = Number(args.capture || 0); + // eslint-disable-next-line max-len super(`A wait of ${seconds} seconds is required before sending another message in this chat${RPCError._fmtRequest(args.request)}`); + // eslint-disable-next-line max-len this.message = `A wait of ${seconds} seconds is required before sending another message in this chat${RPCError._fmtRequest(args.request)}`; this.seconds = seconds; } @@ -47,6 +53,7 @@ class FloodTestPhoneWaitError extends FloodError { constructor(args) { const seconds = Number(args.capture || 0); super(`A wait of ${seconds} seconds is required in the test servers${RPCError._fmtRequest(args.request)}`); + // eslint-disable-next-line max-len this.message = `A wait of ${seconds} seconds is required in the test servers${RPCError._fmtRequest(args.request)}`; this.seconds = seconds; } @@ -56,6 +63,7 @@ class FileMigrateError extends InvalidDCError { constructor(args) { const newDc = Number(args.capture || 0); super(`The file to be accessed is currently stored in DC ${newDc}${RPCError._fmtRequest(args.request)}`); + // eslint-disable-next-line max-len this.message = `The file to be accessed is currently stored in DC ${newDc}${RPCError._fmtRequest(args.request)}`; this.newDc = newDc; } @@ -74,6 +82,7 @@ class EmailUnconfirmedError extends BadRequestError { constructor(args) { const codeLength = Number(args.capture || 0); super(`Email unconfirmed, the length of the code must be ${codeLength}${RPCError._fmtRequest(args.request)}`); + // eslint-disable-next-line max-len this.message = `Email unconfirmed, the length of the code must be ${codeLength}${RPCError._fmtRequest(args.request)}`; this.codeLength = codeLength; } diff --git a/src/lib/gramjs/errors/index.js b/src/lib/gramjs/errors/index.js index bb1588c22..7308fa02f 100644 --- a/src/lib/gramjs/errors/index.js +++ b/src/lib/gramjs/errors/index.js @@ -11,7 +11,7 @@ function RPCMessageToError(rpcError, request) { for (const [msgRegex, Cls] of rpcErrorRe) { const m = rpcError.errorMessage.match(msgRegex); if (m) { - const capture = m.length === 2 ? parseInt(m[1]) : null; + const capture = m.length === 2 ? parseInt(m[1], 10) : undefined; return new Cls({ request, capture, @@ -22,9 +22,13 @@ function RPCMessageToError(rpcError, request) { return new RPCError(rpcError.errorMessage, request); } +const Common = require('./Common'); +const RPCBaseErrors = require('./RPCBaseErrors'); +const RPCErrorList = require('./RPCErrorList'); + module.exports = { RPCMessageToError, - ...require('./Common'), - ...require('./RPCBaseErrors'), - ...require('./RPCErrorList'), + ...Common, + ...RPCBaseErrors, + ...RPCErrorList, }; diff --git a/src/lib/gramjs/events/Raw.js b/src/lib/gramjs/events/Raw.js index b379b831d..0d39470e5 100644 --- a/src/lib/gramjs/events/Raw.js +++ b/src/lib/gramjs/events/Raw.js @@ -2,8 +2,8 @@ const { EventBuilder } = require('./common'); class Raw extends EventBuilder { constructor(args = { - types: null, - func: null, + types: undefined, + func: undefined, }) { super(); if (!args.types) { @@ -13,7 +13,7 @@ class Raw extends EventBuilder { } } - build(update, others = null) { + build(update) { return update; } } diff --git a/src/lib/gramjs/events/common.js b/src/lib/gramjs/events/common.js index 57a133031..a2980f0ad 100644 --- a/src/lib/gramjs/events/common.js +++ b/src/lib/gramjs/events/common.js @@ -1,8 +1,8 @@ class EventBuilder { constructor(args = { - chats: null, - blacklistChats: null, - func: null, + chats: undefined, + blacklistChats: undefined, + func: undefined, }) { this.chats = args.chats; this.blacklistChats = Boolean(args.blacklistChats); @@ -10,17 +10,13 @@ class EventBuilder { this.func = args.func; } - build(update, others = null) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + build(update) { } } -class EventCommon { - -} - module.exports = { EventBuilder, - EventCommon, }; diff --git a/src/lib/gramjs/extensions/BinaryReader.js b/src/lib/gramjs/extensions/BinaryReader.js index 38e503efb..99d1301f5 100644 --- a/src/lib/gramjs/extensions/BinaryReader.js +++ b/src/lib/gramjs/extensions/BinaryReader.js @@ -10,7 +10,7 @@ class BinaryReader { */ constructor(data) { this.stream = data; - this._last = null; + this._last = undefined; this.offset = 0; } @@ -234,7 +234,7 @@ class BinaryReader { * Closes the reader. */ close() { - this.stream = null; + this.stream = undefined; } // region Position related diff --git a/src/lib/gramjs/extensions/Logger.js b/src/lib/gramjs/extensions/Logger.js index 6a303e26d..62297b736 100644 --- a/src/lib/gramjs/extensions/Logger.js +++ b/src/lib/gramjs/extensions/Logger.js @@ -1,4 +1,4 @@ -let _level = null; +let _level; class Logger { static levels = ['error', 'warn', 'info', 'debug']; @@ -92,12 +92,12 @@ class Logger { } if (this.canSend(level)) { if (!this.isBrowser) { + // eslint-disable-next-line no-console console.log(color + this.format(message, level) + this.colors.end); } else { + // eslint-disable-next-line no-console console.log(this.colors.start + this.format(message, level), color); } - } else { - } } } diff --git a/src/lib/gramjs/extensions/MessagePacker.js b/src/lib/gramjs/extensions/MessagePacker.js index cd8f19e14..2de2f98ef 100644 --- a/src/lib/gramjs/extensions/MessagePacker.js +++ b/src/lib/gramjs/extensions/MessagePacker.js @@ -49,7 +49,7 @@ class MessagePacker { } if (!this._queue[this._queue.length - 1]) { this._queue = []; - return; + return undefined; } let data; let buffer = new BinaryWriter(Buffer.alloc(0)); @@ -69,7 +69,8 @@ class MessagePacker { buffer, state.data, state.request.classType === 'request', afterId, ); - this._log.debug(`Assigned msgId = ${state.msgId} to ${state.request.className || state.request.constructor.name}`); + this._log.debug(`Assigned msgId = ${state.msgId} to ${state.request.className + || state.request.constructor.name}`); batch.push(state); continue; } @@ -77,12 +78,13 @@ class MessagePacker { this._queue.unshift(state); break; } - this._log.warn(`Message payload for ${state.request.className || state.request.constructor.name} is too long ${state.data.length} and cannot be sent`); + this._log.warn(`Message payload for ${state.request.className + || state.request.constructor.name} is too long ${state.data.length} and cannot be sent`); state.reject('Request Payload is too big'); size = 0; } if (!batch.length) { - return null; + return undefined; } if (batch.length > 1) { const b = Buffer.alloc(8); diff --git a/src/lib/gramjs/extensions/PromisedWebSockets.js b/src/lib/gramjs/extensions/PromisedWebSockets.js index 838f89f48..cce61e68a 100644 --- a/src/lib/gramjs/extensions/PromisedWebSockets.js +++ b/src/lib/gramjs/extensions/PromisedWebSockets.js @@ -15,12 +15,13 @@ class PromisedWebSockets { process.__nwjs */ - this.client = null; + this.client = undefined; this.closed = true; } async readExactly(number) { let readData = Buffer.alloc(0); + // eslint-disable-next-line no-constant-condition while (true) { const thisTime = await this.read(number); readData = Buffer.concat([readData, thisTime]); @@ -71,7 +72,7 @@ class PromisedWebSockets { } } - async connect(port, ip) { + connect(port, ip) { this.stream = Buffer.alloc(0); this.canRead = new Promise((resolve) => { this.resolveRead = resolve; @@ -93,6 +94,7 @@ class PromisedWebSockets { }; // CONTEST // Seems to not be working, at least in a web worker + // eslint-disable-next-line no-restricted-globals self.addEventListener('offline', async () => { await this.close(); this.resolveRead(false); @@ -112,7 +114,7 @@ class PromisedWebSockets { this.closed = true; } - async receive() { + receive() { this.client.onmessage = async (message) => { const release = await mutex.acquire(); try { diff --git a/src/lib/gramjs/network/Authenticator.js b/src/lib/gramjs/network/Authenticator.js index 36f431325..66a582461 100644 --- a/src/lib/gramjs/network/Authenticator.js +++ b/src/lib/gramjs/network/Authenticator.js @@ -58,16 +58,16 @@ async function doAuthentication(sender, log) { }); // sha_digest + data + random_bytes - let cipherText = null; - let targetFingerprint = null; + let cipherText; + let targetFingerprint; for (const fingerprint of resPQ.serverPublicKeyFingerprints) { cipherText = await RSA.encrypt(fingerprint.toString(), pqInnerData.getBytes()); - if (cipherText !== null && cipherText !== undefined) { + if (cipherText !== undefined) { targetFingerprint = fingerprint; break; } } - if (cipherText === null || cipherText === undefined) { + if (cipherText === undefined) { throw new SecurityError('Step 2 could not find a valid key for fingerprints'); } @@ -81,7 +81,8 @@ async function doAuthentication(sender, log) { encryptedData: cipherText, }), ); - if (!(serverDhParams instanceof constructors.ServerDHParamsOk || serverDhParams instanceof constructors.ServerDHParamsFail)) { + if (!(serverDhParams instanceof constructors.ServerDHParamsOk + || serverDhParams instanceof constructors.ServerDHParamsFail)) { throw new Error(`Step 2.1 answer was ${serverDhParams}`); } if (serverDhParams.nonce.neq(resPQ.nonce)) { diff --git a/src/lib/gramjs/network/MTProtoPlainSender.js b/src/lib/gramjs/network/MTProtoPlainSender.js index a071ade18..361746efd 100644 --- a/src/lib/gramjs/network/MTProtoPlainSender.js +++ b/src/lib/gramjs/network/MTProtoPlainSender.js @@ -3,7 +3,6 @@ * in plain text, when no authorization key has been created yet. */ const BigInt = require('big-integer'); -const Helpers = require('../Helpers'); const MTProtoState = require('./MTProtoState'); const BinaryReader = require('../extensions/BinaryReader'); const { InvalidBufferError } = require('../errors/Common'); diff --git a/src/lib/gramjs/network/MTProtoSender.js b/src/lib/gramjs/network/MTProtoSender.js index a29cb5426..6252c7d1d 100644 --- a/src/lib/gramjs/network/MTProtoSender.js +++ b/src/lib/gramjs/network/MTProtoSender.js @@ -50,16 +50,16 @@ const { TypeNotFoundError } = require('../errors/Common'); */ class MTProtoSender { static DEFAULT_OPTIONS = { - logger: null, + logger: undefined, retries: Infinity, delay: 2000, autoReconnect: true, - connectTimeout: null, - authKeyCallback: null, - updateCallback: null, - autoReconnectCallback: null, - isMainSender: null, - onConnectionBreak: null, + connectTimeout: undefined, + authKeyCallback: undefined, + updateCallback: undefined, + autoReconnectCallback: undefined, + isMainSender: undefined, + onConnectionBreak: undefined, }; /** @@ -68,7 +68,7 @@ class MTProtoSender { */ constructor(authKey, opts) { const args = { ...MTProtoSender.DEFAULT_OPTIONS, ...opts }; - this._connection = null; + this._connection = undefined; this._log = args.logger; this._dcId = args.dcId; this._retries = args.retries; @@ -96,8 +96,8 @@ class MTProtoSender { /** * We need to join the loops upon disconnection */ - this._send_loop_handle = null; - this._recv_loop_handle = null; + this._send_loop_handle = undefined; + this._recv_loop_handle = undefined; /** * Preserving the references of the AuthKey and state is important @@ -180,6 +180,7 @@ class MTProtoSender { await Helpers.sleep(this._delay); } } + return true; } isConnected() { @@ -286,10 +287,10 @@ class MTProtoSender { this._log.info('Connection to %s complete!'.replace('%s', this._connection.toString())); } - async _disconnect(error = null) { + async _disconnect() { this._send_queue.rejectAll(); - if (this._connection === null) { + if (this._connection === undefined) { this._log.info('Not disconnecting (already have no connection)'); return; } @@ -495,12 +496,12 @@ class MTProtoSender { * @private */ _handleRPCResult(message) { - const RPCResult = message.obj; - const state = this._pending_state[RPCResult.reqMsgId]; + const result = message.obj; + const state = this._pending_state[result.reqMsgId]; if (state) { - delete this._pending_state[RPCResult.reqMsgId]; + delete this._pending_state[result.reqMsgId]; } - this._log.debug(`Handling RPC result for message ${RPCResult.reqMsgId}`); + this._log.debug(`Handling RPC result for message ${result.reqMsgId}`); if (!state) { // TODO We should not get responses to things we never sent @@ -508,27 +509,27 @@ class MTProtoSender { // See #658, #759 and #958. They seem to happen in a container // which contain the real response right after. try { - const reader = new BinaryReader(RPCResult.body); + const reader = new BinaryReader(result.body); if (!(reader.tgReadObject() instanceof upload.File)) { throw new TypeNotFoundError('Not an upload.File'); } } catch (e) { this._log.error(e); if (e instanceof TypeNotFoundError) { - this._log.info(`Received response without parent request: ${RPCResult.body}`); + this._log.info(`Received response without parent request: ${result.body}`); return; } else { throw e; } } } - if (RPCResult.error) { + if (result.error) { // eslint-disable-next-line new-cap - const error = RPCMessageToError(RPCResult.error, state.request); + const error = RPCMessageToError(result.error, state.request); this._send_queue.append(new RequestState(new MsgsAck({ msgIds: [state.msgId] }))); state.reject(error); } else { - const reader = new BinaryReader(RPCResult.body); + const reader = new BinaryReader(result.body); const read = state.request.readResult(reader); state.resolve(read); } @@ -562,7 +563,7 @@ class MTProtoSender { await this._processMessage(message); } - async _handleUpdate(message) { + _handleUpdate(message) { if (message.obj.SUBCLASS_OF_ID !== 0x8af52aac) { // crc32(b'Updates') this._log.warn(`Note: ${message.obj.className} is not an update, not dispatching it`); @@ -582,7 +583,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handlePong(message) { + _handlePong(message) { const pong = message.obj; this._log.debug(`Handling pong for message ${pong.msgId}`); const state = this._pending_state[pong.msgId]; @@ -603,7 +604,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleBadServerSalt(message) { + _handleBadServerSalt(message) { const badSalt = message.obj; this._log.debug(`Handling bad salt for message ${badSalt.badMsgId}`); this._state.salt = badSalt.newServerSalt; @@ -621,7 +622,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleBadNotification(message) { + _handleBadNotification(message) { const badMsg = message.obj; const states = this._popStates(badMsg.badMsgId); this._log.debug(`Handling bad msg ${JSON.stringify(badMsg)}`); @@ -657,7 +658,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleDetailedInfo(message) { + _handleDetailedInfo(message) { // TODO https://goo.gl/VvpCC6 const msgId = message.obj.answerMsgId; this._log.debug(`Handling detailed info for message ${msgId}`); @@ -672,7 +673,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleNewDetailedInfo(message) { + _handleNewDetailedInfo(message) { // TODO https://goo.gl/VvpCC6 const msgId = message.obj.answerMsgId; this._log.debug(`Handling new detailed info for message ${msgId}`); @@ -687,7 +688,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleNewSessionCreated(message) { + _handleNewSessionCreated(message) { // TODO https://goo.gl/LMyN7A this._log.debug('Handling new session created'); this._state.salt = message.obj.serverSalt; @@ -711,7 +712,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleAck(message) { + _handleAck(message) { const ack = message.obj; this._log.debug(`Handling acknowledge for ${ack.msgIds}`); for (const msgId of ack.msgIds) { @@ -732,7 +733,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleFutureSalts(message) { + _handleFutureSalts(message) { // TODO save these salts and automatically adjust to the // correct one whenever the salt in use expires. this._log.debug(`Handling future salts for message ${message.msgId}`); @@ -751,7 +752,7 @@ class MTProtoSender { * @returns {Promise} * @private */ - async _handleStateForgotten(message) { + _handleStateForgotten(message) { this._send_queue.append( new RequestState(new MsgsStateInfo(message.msgId, String.fromCharCode(1) .repeat(message.obj.msgIds))), @@ -760,14 +761,17 @@ class MTProtoSender { /** * Handles :tl:`MsgsAllInfo` by doing nothing (yet). + * used as part of the telegram protocol https://core.telegram.org/mtproto/service_messages_about_messages + * This message does not require an acknowledgment. * @param message * @returns {Promise} * @private */ - async _handleMsgAll(message) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _handleMsgAll(message) { } - async reconnect() { + reconnect() { if (this._user_connected && !this._reconnecting) { this._reconnecting = true; // TODO Should we set this? @@ -785,7 +789,7 @@ class MTProtoSender { this._log.warn(err); } - this._send_queue.append(null); + this._send_queue.append(undefined); this._state.reset(); await this.connect(this._connection, true); diff --git a/src/lib/gramjs/network/MTProtoState.js b/src/lib/gramjs/network/MTProtoState.js index 83ef93812..9f635b1cb 100644 --- a/src/lib/gramjs/network/MTProtoState.js +++ b/src/lib/gramjs/network/MTProtoState.js @@ -1,3 +1,5 @@ +const BigInt = require('big-integer'); + const Helpers = require('../Helpers'); const IGE = require('../crypto/IGE'); const BinaryReader = require('../extensions/BinaryReader'); @@ -8,12 +10,9 @@ const { InvalidBufferError, } = require('../errors/Common'); const { InvokeAfterMsg } = require('../tl').requests; -const BigInt = require('big-integer'); const { toSignedLittleBuffer, - readBufferFromBigInt, } = require('../Helpers'); -const { readBigIntFromBuffer } = require('../Helpers'); class MTProtoState { /** @@ -47,7 +46,9 @@ class MTProtoState { this.timeOffset = 0; this.salt = 0; - this.id = this._sequence = this._lastMsgId = null; + this.id = undefined; + this._sequence = undefined; + this._lastMsgId = undefined; this.reset(); } diff --git a/src/lib/gramjs/network/RequestState.js b/src/lib/gramjs/network/RequestState.js index 0d9297ad3..30bb94312 100644 --- a/src/lib/gramjs/network/RequestState.js +++ b/src/lib/gramjs/network/RequestState.js @@ -1,11 +1,11 @@ class RequestState { - constructor(request, after = null) { - this.containerId = null; - this.msgId = null; + constructor(request, after = undefined) { + this.containerId = undefined; + this.msgId = undefined; this.request = request; this.data = request.getBytes(); this.after = after; - this.result = null; + this.result = undefined; this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; diff --git a/src/lib/gramjs/network/connection/Connection.js b/src/lib/gramjs/network/connection/Connection.js index ac8ae19ed..38280a96d 100644 --- a/src/lib/gramjs/network/connection/Connection.js +++ b/src/lib/gramjs/network/connection/Connection.js @@ -13,7 +13,7 @@ const AsyncQueue = require('../../extensions/AsyncQueue'); * the client is disconnected (includes remote disconnections). */ class Connection { - PacketCodecClass = null; + PacketCodecClass = undefined; constructor(ip, port, dcId, loggers) { this._ip = ip; @@ -21,10 +21,10 @@ class Connection { this._dcId = dcId; this._log = loggers; this._connected = false; - this._sendTask = null; - this._recvTask = null; - this._codec = null; - this._obfuscation = null; // TcpObfuscated and MTProxy + this._sendTask = undefined; + this._recvTask = undefined; + this._codec = undefined; + this._obfuscation = undefined; // TcpObfuscated and MTProxy this._sendArray = new AsyncQueue(); this._recvArray = new AsyncQueue(); // this.socket = new PromiseSocket(new Socket()) @@ -53,7 +53,7 @@ class Connection { async disconnect() { this._connected = false; - await this._recvArray.push(null); + await this._recvArray.push(undefined); await this.socket.close(); } @@ -81,7 +81,7 @@ class Connection { while (this._connected) { const data = await this._sendArray.pop(); if (!data) { - this._sendTask = null; + this._sendTask = undefined; return; } await this._send(data); @@ -116,13 +116,13 @@ class Connection { } } - async _send(data) { + _send(data) { const encodedPacket = this._codec.encodePacket(data); this.socket.write(encodedPacket); } - async _recv() { - return await this._codec.readPacket(this.socket); + _recv() { + return this._codec.readPacket(this.socket); } toString() { @@ -131,9 +131,9 @@ class Connection { } class ObfuscatedConnection extends Connection { - ObfuscatedIO = null; + ObfuscatedIO = undefined; - async _initConn() { + _initConn() { this._obfuscation = new this.ObfuscatedIO(this); this.socket.write(this._obfuscation.header); } @@ -143,8 +143,8 @@ class ObfuscatedConnection extends Connection { } - async _recv() { - return await this._codec.readPacket(this._obfuscation); + _recv() { + return this._codec.readPacket(this._obfuscation); } } @@ -153,13 +153,15 @@ class PacketCodec { this._conn = connection; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars encodePacket(data) { throw new Error('Not Implemented'); // Override } - async readPacket(reader) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + readPacket(reader) { // override throw new Error('Not Implemented'); } diff --git a/src/lib/gramjs/network/connection/TCPAbridged.js b/src/lib/gramjs/network/connection/TCPAbridged.js index ab183ec3a..5876d3f98 100644 --- a/src/lib/gramjs/network/connection/TCPAbridged.js +++ b/src/lib/gramjs/network/connection/TCPAbridged.js @@ -36,7 +36,7 @@ class AbridgedPacketCodec extends PacketCodec { .readInt32LE(0); } - return await reader.read(length << 2); + return reader.read(length << 2); } } diff --git a/src/lib/gramjs/network/connection/TCPObfuscated.js b/src/lib/gramjs/network/connection/TCPObfuscated.js index cf1961580..dc3ccdf5a 100644 --- a/src/lib/gramjs/network/connection/TCPObfuscated.js +++ b/src/lib/gramjs/network/connection/TCPObfuscated.js @@ -4,7 +4,7 @@ const { AbridgedPacketCodec } = require('./TCPAbridged'); const CTR = require('../../crypto/CTR'); class ObfuscatedIO { - header = null; + header = undefined; constructor(connection) { this.connection = connection.socket; diff --git a/src/lib/gramjs/sessions/Abstract.js b/src/lib/gramjs/sessions/Abstract.js index 46c378dbb..1c30ebc13 100644 --- a/src/lib/gramjs/sessions/Abstract.js +++ b/src/lib/gramjs/sessions/Abstract.js @@ -1,8 +1,4 @@ class Session { - constructor() { - - } - /** * Creates a clone of this session file * @param toInstance {Session|null} @@ -59,6 +55,7 @@ class Session { * @param serverAddress {string} * @param port {number} */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars setDC(dcId, serverAddress, port) { throw new Error('Not implemented'); } diff --git a/src/lib/gramjs/sessions/CacheApiSession.js b/src/lib/gramjs/sessions/CacheApiSession.js index 99d7ca3bb..5bd45aa4b 100644 --- a/src/lib/gramjs/sessions/CacheApiSession.js +++ b/src/lib/gramjs/sessions/CacheApiSession.js @@ -1,3 +1,4 @@ +/* eslint-disable no-restricted-globals */ const StorageSession = require('./StorageSession'); const CACHE_NAME = 'GramJs'; @@ -13,7 +14,7 @@ class CacheApiSession extends StorageSession { const request = new Request(this._storageKey); const cache = await self.caches.open(CACHE_NAME); const cached = await cache.match(request); - return cached ? cached.text() : null; + return cached ? cached.text() : undefined; } async _saveToCache(data) { diff --git a/src/lib/gramjs/sessions/IdbSession.js b/src/lib/gramjs/sessions/IdbSession.js index 4da760af9..42dfa39aa 100644 --- a/src/lib/gramjs/sessions/IdbSession.js +++ b/src/lib/gramjs/sessions/IdbSession.js @@ -4,15 +4,15 @@ const StorageSession = require('./StorageSession'); const CACHE_NAME = 'GramJs'; class IdbSession extends StorageSession { - async _delete() { + _delete() { return idb.del(`${CACHE_NAME}:${this._storageKey}`); } - async _fetchFromCache() { + _fetchFromCache() { return idb.get(`${CACHE_NAME}:${this._storageKey}`); } - async _saveToCache(data) { + _saveToCache(data) { return idb.set(`${CACHE_NAME}:${this._storageKey}`, data); } } diff --git a/src/lib/gramjs/sessions/LocalStorageSession.js b/src/lib/gramjs/sessions/LocalStorageSession.js index c042c975e..b64b982cc 100644 --- a/src/lib/gramjs/sessions/LocalStorageSession.js +++ b/src/lib/gramjs/sessions/LocalStorageSession.js @@ -1,15 +1,15 @@ const StorageSession = require('./StorageSession'); class LocalStorageSession extends StorageSession { - async _delete() { + _delete() { return localStorage.removeItem(this._storageKey); } - async _fetchFromCache(key) { + _fetchFromCache() { return localStorage.getItem(this._storageKey); } - async _saveToCache(key, data) { + _saveToCache(data) { return localStorage.setItem(this._storageKey, data); } } diff --git a/src/lib/gramjs/sessions/Memory.js b/src/lib/gramjs/sessions/Memory.js index 520f8d66c..5c2950333 100644 --- a/src/lib/gramjs/sessions/Memory.js +++ b/src/lib/gramjs/sessions/Memory.js @@ -1,15 +1,13 @@ -const utils = require('../Utils'); -const types = require('../tl').constructors; const Session = require('./Abstract'); class MemorySession extends Session { constructor() { super(); - this._serverAddress = null; + this._serverAddress = undefined; this._dcId = 0; - this._port = null; - this._takeoutId = null; + this._port = undefined; + this._takeoutId = undefined; this._entities = new Set(); this._updateStates = {}; diff --git a/src/lib/gramjs/sessions/StorageSession.js b/src/lib/gramjs/sessions/StorageSession.js index 1dd9ac590..4956cfd4b 100644 --- a/src/lib/gramjs/sessions/StorageSession.js +++ b/src/lib/gramjs/sessions/StorageSession.js @@ -48,7 +48,9 @@ class StorageSession extends MemorySession { } }); } catch (err) { + // eslint-disable-next-line no-console console.warn('Failed to retrieve or parse session from storage'); + // eslint-disable-next-line no-console console.warn(err); } } @@ -101,12 +103,15 @@ class StorageSession extends MemorySession { const authKey = this._authKeys[dcId]; sessionData.keys[dcId] = authKey._key; sessionData.hashes[dcId] = authKey._hash; + return undefined; }); try { await this._saveToCache(JSON.stringify(sessionData)); } catch (err) { + // eslint-disable-next-line no-console console.warn('Failed to update session in storage'); + // eslint-disable-next-line no-console console.warn(err); } } @@ -115,23 +120,27 @@ class StorageSession extends MemorySession { try { return await this._delete(); } catch (err) { + // eslint-disable-next-line no-console console.warn('Failed to delete session from storage'); + // eslint-disable-next-line no-console console.warn(err); } + return undefined; } // @abstract - async _delete() { + _delete() { throw new Error('Not Implemented'); } // @abstract - async _fetchFromCache() { + _fetchFromCache() { throw new Error('Not Implemented'); } // @abstract - async _saveToCache(data) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _saveToCache(data) { throw new Error('Not Implemented'); } } diff --git a/src/lib/gramjs/sessions/StringSession.js b/src/lib/gramjs/sessions/StringSession.js index ff2b8815e..2f49da376 100644 --- a/src/lib/gramjs/sessions/StringSession.js +++ b/src/lib/gramjs/sessions/StringSession.js @@ -21,7 +21,7 @@ class StringSession extends MemorySession { * `decode` definition must be ``function decode(value: string) -> Buffer:``. * @param session {string|null} */ - constructor(session = null) { + constructor(session = undefined) { super(); if (session) { if (session[0] !== CURRENT_VERSION) { @@ -96,7 +96,7 @@ class StringSession extends MemorySession { setAuthKey(authKey, dcId) { if (dcId && dcId !== this.dcId) { // Not supported. - return undefined; + return; } this.authKey = authKey; diff --git a/src/lib/gramjs/tl/MTProtoRequest.js b/src/lib/gramjs/tl/MTProtoRequest.js index 31d5d9cd2..73216c3a1 100644 --- a/src/lib/gramjs/tl/MTProtoRequest.js +++ b/src/lib/gramjs/tl/MTProtoRequest.js @@ -34,10 +34,14 @@ class MTProtoRequest { throw Error(`Not overload ${this.constructor.name}`); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars onResponse(buffer) { + throw Error(`Not overload ${this.constructor.name}`); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars onException(exception) { + throw Error(`Not overload ${this.constructor.name}`); } } diff --git a/src/lib/gramjs/tl/api.js b/src/lib/gramjs/tl/api.js index 2c0310f0e..04bf85ff4 100644 --- a/src/lib/gramjs/tl/api.js +++ b/src/lib/gramjs/tl/api.js @@ -4,7 +4,6 @@ const { serializeDate, } = require('./generationHelpers'); const { - readBufferFromBigInt, toSignedLittleBuffer, } = require('../Helpers'); @@ -32,6 +31,7 @@ const AUTO_CASTS = new Set([ ]) */ +// eslint-disable-next-line no-restricted-globals const CACHING_SUPPORTED = typeof self !== 'undefined' && self.localStorage !== undefined; const CACHE_KEY = 'GramJs:apiCache'; @@ -93,27 +93,33 @@ function extractParams(fileContent) { const constructors = []; const functions = []; for (const d of f) { - d.isFunction ? functions.push(d) : constructors.push(d); + if (d.isFunction) { + functions.push(d); + } else { + constructors.push(d); + } } return [constructors, functions]; } function argToBytes(x, type) { switch (type) { - case 'int': + case 'int': { const i = Buffer.alloc(4); i.writeInt32LE(x, 0); return i; + } case 'long': return toSignedLittleBuffer(x, 8); case 'int128': return toSignedLittleBuffer(x, 16); case 'int256': return toSignedLittleBuffer(x, 32); - case 'double': + case 'double': { const d = Buffer.alloc(8); d.writeDoubleLE(x, 0); return d; + } case 'string': return serializeBytes(x); case 'Bool': @@ -201,7 +207,7 @@ function getArgFromReader(reader, arg) { if (!arg.skipConstructorId) { return reader.tgReadObject(); } else { - return api.constructors[arg.type].fromReader(reader); + throw new Error(`Unknown type ${arg}`); } } } @@ -254,13 +260,13 @@ function createClasses(classesType, params) { const arg = argsConfig[argName]; if (arg.isFlag) { if (arg.type === 'true') { - args[argName] = Boolean(args.flags & 1 << arg.flagIndex); + args[argName] = Boolean(args.flags & (1 << arg.flagIndex)); continue; } - if (args.flags & 1 << arg.flagIndex) { + if (args.flags & (1 << arg.flagIndex)) { args[argName] = getArgFromReader(reader, arg); } else { - args[argName] = null; + args[argName] = undefined; } } else { if (arg.flagIndicator) { @@ -282,7 +288,8 @@ function createClasses(classesType, params) { for (const arg in argsConfig) { if (argsConfig.hasOwnProperty(arg)) { if (argsConfig[arg].isFlag) { - if ((this[arg] === false && argsConfig[arg].type === 'true') || this[arg] === null || this[arg] === undefined) { + if ((this[arg] === false && argsConfig[arg].type === 'true') + || this[arg] === undefined) { continue; } } @@ -301,7 +308,8 @@ function createClasses(classesType, params) { let flagCalculate = 0; for (const f in argsConfig) { if (argsConfig[f].isFlag) { - if ((this[f] === false && argsConfig[f].type === 'true') || this[f] === undefined || this[f] === null) { + if ((this[f] === false && argsConfig[f].type === 'true') + || this[f] === undefined) { flagCalculate |= 0; } else { flagCalculate |= 1 << argsConfig[f].flagIndex; diff --git a/src/lib/gramjs/tl/core/GZIPPacked.js b/src/lib/gramjs/tl/core/GZIPPacked.js index 438e3fbda..204f881d4 100644 --- a/src/lib/gramjs/tl/core/GZIPPacked.js +++ b/src/lib/gramjs/tl/core/GZIPPacked.js @@ -34,12 +34,12 @@ class GZIPPacked { return Buffer.from(inflate(input)); } - static async read(reader) { + static read(reader) { const constructor = reader.readInt(false); if (constructor !== GZIPPacked.CONSTRUCTOR_ID) { throw new Error('not equal'); } - return await GZIPPacked.gzip(reader.tgReadBytes()); + return GZIPPacked.gzip(reader.tgReadBytes()); } static async fromReader(reader) { diff --git a/src/lib/gramjs/tl/core/MessageContainer.js b/src/lib/gramjs/tl/core/MessageContainer.js index e76092c12..879003449 100644 --- a/src/lib/gramjs/tl/core/MessageContainer.js +++ b/src/lib/gramjs/tl/core/MessageContainer.js @@ -26,16 +26,16 @@ class MessageContainer { this.classType = 'constructor'; } - static async fromReader(reader) { + static fromReader(reader) { const messages = []; const length = reader.readInt(); for (let x = 0; x < length; x++) { const msgId = reader.readLong(); const seqNo = reader.readInt(); - const length = reader.readInt(); + const containerLength = reader.readInt(); const before = reader.tellPosition(); const obj = reader.tgReadObject(); - reader.setPosition(before + length); + reader.setPosition(before + containerLength); const tlMessage = new TLMessage(msgId, seqNo, obj); messages.push(tlMessage); } diff --git a/src/lib/gramjs/tl/core/RPCResult.js b/src/lib/gramjs/tl/core/RPCResult.js index 1fb1ab383..8c4ef9590 100644 --- a/src/lib/gramjs/tl/core/RPCResult.js +++ b/src/lib/gramjs/tl/core/RPCResult.js @@ -18,7 +18,7 @@ class RPCResult { const msgId = reader.readLong(); const innerCode = reader.readInt(false); if (innerCode === RpcError.CONSTRUCTOR_ID) { - return new RPCResult(msgId, null, RpcError.fromReader(reader)); + return new RPCResult(msgId, undefined, RpcError.fromReader(reader)); } if (innerCode === GZIPPacked.CONSTRUCTOR_ID) { return new RPCResult(msgId, (await GZIPPacked.fromReader(reader)).data); @@ -27,7 +27,7 @@ class RPCResult { // This reader.read() will read more than necessary, but it's okay. // We could make use of MessageContainer's length here, but since // it's not necessary we don't need to care about it. - return new RPCResult(msgId, reader.read(), null); + return new RPCResult(msgId, reader.read(), undefined); } } diff --git a/src/lib/gramjs/tl/generationHelpers.js b/src/lib/gramjs/tl/generationHelpers.js index c7085667a..56faa83fc 100644 --- a/src/lib/gramjs/tl/generationHelpers.js +++ b/src/lib/gramjs/tl/generationHelpers.js @@ -44,7 +44,7 @@ function makeCRCTable() { return crcTable; } -let crcTable = null; +let crcTable; function crc32(buf) { if (!crcTable) { @@ -62,6 +62,21 @@ function crc32(buf) { return (crc ^ (-1)) >>> 0; } +const findAll = (regex, str, matches = []) => { + if (!regex.flags.includes('g')) { + regex = new RegExp(regex.source, 'g'); + } + + const res = regex.exec(str); + + if (res) { + matches.push(res.slice(1)); + findAll(regex, str, matches); + } + + return matches; +}; + const fromLine = (line, isFunction) => { const match = line.match(/([\w.]+)(?:#([0-9a-fA-F]+))?(?:\s{?\w+:[\w\d<>#.?!]+}?)*\s=\s([\w\d<>#.?]+);$/); if (!match) { @@ -77,7 +92,7 @@ const fromLine = (line, isFunction) => { subclassOfId: crc32(match[3]), result: match[3], isFunction, - namespace: null, + namespace: undefined, }; if (!currentConfig.constructorId) { const hexId = ''; @@ -134,16 +149,10 @@ function buildArgConfig(name, argType) { skipConstructorId: false, flagIndex: -1, flagIndicator: true, - type: null, - useVectorId: null, + type: undefined, + useVectorId: undefined, }; - // Special case: some types can be inferred, which makes it - // less annoying to type. Currently the only type that can - // be inferred is if the name is 'random_id', to which a - // random ID will be assigned if left as None (the default) - const canBeInferred = name === 'random_id'; - // The type can be an indicator that other arguments will be flags if (argType !== '#') { currentConfig.flagIndicator = false; @@ -206,8 +215,8 @@ function buildArgConfig(name, argType) { } -const parseTl = function* (content, layer, methods = [], ignoreIds = CORE_TYPES) { - const methodInfo = (methods || []).reduce((o, m) => ({ +function* parseTl(content, layer, methods = [], ignoreIds = CORE_TYPES) { + (methods || []).reduce((o, m) => ({ ...o, [m.name]: m, }), {}); @@ -281,22 +290,7 @@ const parseTl = function* (content, layer, methods = [], ignoreIds = CORE_TYPES) for (const obj of objAll) { yield obj; } -}; - -const findAll = (regex, str, matches = []) => { - if (!regex.flags.includes('g')) { - regex = new RegExp(regex.source, 'g'); - } - - const res = regex.exec(str); - - if (res) { - matches.push(res.slice(1)); - findAll(regex, str, matches); - } - - return matches; -}; +} function serializeBytes(data) { if (!(data instanceof Buffer)) { diff --git a/src/lib/gramjs/tl/index.js b/src/lib/gramjs/tl/index.js index 107ef6fa1..df41fd228 100644 --- a/src/lib/gramjs/tl/index.js +++ b/src/lib/gramjs/tl/index.js @@ -4,13 +4,10 @@ const { serializeDate, } = require('./generationHelpers'); -const patched = null; - module.exports = { // TODO Refactor internal usages to always use `api`. constructors: api, requests: api, - patched, serializeBytes, serializeDate, };