Explorar o código

Add optional security check
Set the correct destroyed attribute on destroy.

painor %!s(int64=3) %!d(string=hai) anos
pai
achega
61aababfe7

+ 1 - 1
gramjs/Version.ts

@@ -1 +1 @@
-export const version = "2.4.3";
+export const version = "2.4.5";

+ 2 - 0
gramjs/client/TelegramClient.ts

@@ -1333,6 +1333,7 @@ export class TelegramClient extends TelegramBaseClient {
                 updateCallback: _handleUpdate.bind(this),
                 updateCallback: _handleUpdate.bind(this),
                 isMainSender: true,
                 isMainSender: true,
                 client: this,
                 client: this,
+                securityChecks: this._securityChecks,
             });
             });
         }
         }
         // set defaults vars
         // set defaults vars
@@ -1361,6 +1362,7 @@ export class TelegramClient extends TelegramBaseClient {
 
 
         this.session.setAuthKey(this._sender.authKey);
         this.session.setAuthKey(this._sender.authKey);
         this._initRequest.query = new Api.help.GetConfig();
         this._initRequest.query = new Api.help.GetConfig();
+        this._log.info(`Using LAYER ${LAYER} for initial connect`);
         await this._sender.send(
         await this._sender.send(
             new Api.InvokeWithLayer({
             new Api.InvokeWithLayer({
                 layer: LAYER,
                 layer: LAYER,

+ 12 - 5
gramjs/client/telegramBaseClient.ts

@@ -113,6 +113,10 @@ export interface TelegramClientParams {
      * Limits how many downloads happen at the same time.
      * Limits how many downloads happen at the same time.
      */
      */
     maxConcurrentDownloads?: number;
     maxConcurrentDownloads?: number;
+    /**
+     * Whether to check for tampering in messages or not.
+     */
+    securityChecks?: boolean;
 }
 }
 
 
 const clientParamsDefault = {
 const clientParamsDefault = {
@@ -131,6 +135,7 @@ const clientParamsDefault = {
     appVersion: "",
     appVersion: "",
     langCode: "en",
     langCode: "en",
     systemLangCode: "en",
     systemLangCode: "en",
+    _securityChecks: true,
     useWSS:
     useWSS:
         typeof window !== "undefined"
         typeof window !== "undefined"
             ? window.location.protocol == "https:"
             ? window.location.protocol == "https:"
@@ -205,6 +210,7 @@ export abstract class TelegramBaseClient {
     _destroyed: boolean;
     _destroyed: boolean;
     protected _proxy?: ProxyInterface;
     protected _proxy?: ProxyInterface;
     _semaphore: Semaphore;
     _semaphore: Semaphore;
+    _securityChecks: boolean;
     constructor(
     constructor(
         session: string | Session,
         session: string | Session,
         apiId: number,
         apiId: number,
@@ -275,6 +281,7 @@ export abstract class TelegramBaseClient {
         this._bot = undefined;
         this._bot = undefined;
         this._selfInputPeer = undefined;
         this._selfInputPeer = undefined;
         this.useWSS = clientParams.useWSS!;
         this.useWSS = clientParams.useWSS!;
+        this._securityChecks = !!clientParams.securityChecks;
         if (this.useWSS && this._proxy) {
         if (this.useWSS && this._proxy) {
             throw new Error(
             throw new Error(
                 "Cannot use SSL with proxies. You need to disable the useWSS client param in TelegramClient"
                 "Cannot use SSL with proxies. You need to disable the useWSS client param in TelegramClient"
@@ -354,14 +361,12 @@ export abstract class TelegramBaseClient {
 
 
     /**
     /**
      * Disconnects all senders and removes all handlers
      * Disconnects all senders and removes all handlers
-     * @remarks
-     * This will also delete your session (not log out) so be careful with usage.
-     * Disconnect is safer as it will do almost the same while keeping your session file/
+     * Disconnect is safer as it will not remove your event handlers
      */
      */
     async destroy() {
     async destroy() {
+        this._destroyed = true;
         await Promise.all([
         await Promise.all([
             this.disconnect(),
             this.disconnect(),
-            this.session.delete(),
             ...Object.values(this._borrowedSenderPromises).map(
             ...Object.values(this._borrowedSenderPromises).map(
                 (promise: any) => {
                 (promise: any) => {
                     return promise.then((sender: any) => sender.disconnect());
                     return promise.then((sender: any) => sender.disconnect());
@@ -404,7 +409,7 @@ export abstract class TelegramBaseClient {
 
 
                 if (this.session.dcId !== dcId && !sender._authenticated) {
                 if (this.session.dcId !== dcId && !sender._authenticated) {
                     this._log.info(
                     this._log.info(
-                        `Exporting authorization for data center ${dc.ipAddress}`
+                        `Exporting authorization for data center ${dc.ipAddress} with layer ${LAYER}`
                     );
                     );
                     const auth = await this.invoke(
                     const auth = await this.invoke(
                         new Api.auth.ExportAuthorization({ dcId: dcId })
                         new Api.auth.ExportAuthorization({ dcId: dcId })
@@ -413,6 +418,7 @@ export abstract class TelegramBaseClient {
                         id: auth.id,
                         id: auth.id,
                         bytes: auth.bytes,
                         bytes: auth.bytes,
                     });
                     });
+
                     const req = new Api.InvokeWithLayer({
                     const req = new Api.InvokeWithLayer({
                         layer: LAYER,
                         layer: LAYER,
                         query: this._initRequest,
                         query: this._initRequest,
@@ -502,6 +508,7 @@ export abstract class TelegramBaseClient {
             isMainSender: dcId === this.session.dcId,
             isMainSender: dcId === this.session.dcId,
             onConnectionBreak: this._cleanupExportedSender.bind(this),
             onConnectionBreak: this._cleanupExportedSender.bind(this),
             client: this as unknown as TelegramClient,
             client: this as unknown as TelegramClient,
+            securityChecks: this._securityChecks,
         });
         });
     }
     }
 
 

+ 3 - 0
gramjs/client/updates.ts

@@ -173,6 +173,9 @@ export async function _updateLoop(client: TelegramClient): Promise<void> {
         if (client._reconnecting) {
         if (client._reconnecting) {
             continue;
             continue;
         }
         }
+        if (client._destroyed) {
+            return;
+        }
 
 
         try {
         try {
             await attempts(
             await attempts(

+ 13 - 2
gramjs/network/MTProtoSender.ts

@@ -47,6 +47,7 @@ interface DEFAULT_OPTIONS {
     senderCallback?: any;
     senderCallback?: any;
     client: TelegramClient;
     client: TelegramClient;
     onConnectionBreak?: CallableFunction;
     onConnectionBreak?: CallableFunction;
+    securityChecks: boolean;
 }
 }
 
 
 export class MTProtoSender {
 export class MTProtoSender {
@@ -62,6 +63,7 @@ export class MTProtoSender {
         isMainSender: null,
         isMainSender: null,
         senderCallback: null,
         senderCallback: null,
         onConnectionBreak: undefined,
         onConnectionBreak: undefined,
+        securityChecks: true,
     };
     };
     private _connection?: Connection;
     private _connection?: Connection;
     private readonly _log: Logger;
     private readonly _log: Logger;
@@ -95,13 +97,17 @@ export class MTProtoSender {
     userDisconnected: boolean;
     userDisconnected: boolean;
     isConnecting: boolean;
     isConnecting: boolean;
     _authenticated: boolean;
     _authenticated: boolean;
+    private _securityChecks: boolean;
 
 
     /**
     /**
      * @param authKey
      * @param authKey
      * @param opts
      * @param opts
      */
      */
     constructor(authKey: undefined | AuthKey, opts: DEFAULT_OPTIONS) {
     constructor(authKey: undefined | AuthKey, opts: DEFAULT_OPTIONS) {
-        const args = { ...MTProtoSender.DEFAULT_OPTIONS, ...opts };
+        const args = {
+            ...MTProtoSender.DEFAULT_OPTIONS,
+            ...opts,
+        };
         this._connection = undefined;
         this._connection = undefined;
         this._log = args.logger;
         this._log = args.logger;
         this._dcId = args.dcId;
         this._dcId = args.dcId;
@@ -116,6 +122,7 @@ export class MTProtoSender {
         this._senderCallback = args.senderCallback;
         this._senderCallback = args.senderCallback;
         this._client = args.client;
         this._client = args.client;
         this._onConnectionBreak = args.onConnectionBreak;
         this._onConnectionBreak = args.onConnectionBreak;
+        this._securityChecks = args.securityChecks;
 
 
         /**
         /**
          * whether we disconnected ourself or telegram did it.
          * whether we disconnected ourself or telegram did it.
@@ -144,7 +151,11 @@ export class MTProtoSender {
          * Preserving the references of the AuthKey and state is important
          * Preserving the references of the AuthKey and state is important
          */
          */
         this.authKey = authKey || new AuthKey();
         this.authKey = authKey || new AuthKey();
-        this._state = new MTProtoState(this.authKey, this._log);
+        this._state = new MTProtoState(
+            this.authKey,
+            this._log,
+            this._securityChecks
+        );
 
 
         /**
         /**
          * Outgoing messages are put in a queue and sent in a batch.
          * Outgoing messages are put in a queue and sent in a batch.

+ 8 - 2
gramjs/network/MTProtoState.ts

@@ -18,6 +18,7 @@ export class MTProtoState {
     _sequence: number;
     _sequence: number;
     private _lastMsgId: bigInt.BigInteger;
     private _lastMsgId: bigInt.BigInteger;
     private msgIds: string[];
     private msgIds: string[];
+    private securityChecks: boolean;
 
 
     /**
     /**
      *
      *
@@ -43,8 +44,9 @@ export class MTProtoState {
      authentication process, at which point the `MTProtoPlainSender` is better
      authentication process, at which point the `MTProtoPlainSender` is better
      * @param authKey
      * @param authKey
      * @param loggers
      * @param loggers
+     * @param securityChecks
      */
      */
-    constructor(authKey?: AuthKey, loggers?: any) {
+    constructor(authKey?: AuthKey, loggers?: any, securityChecks = true) {
         this.authKey = authKey;
         this.authKey = authKey;
         this._log = loggers;
         this._log = loggers;
         this.timeOffset = 0;
         this.timeOffset = 0;
@@ -52,6 +54,7 @@ export class MTProtoState {
         this._sequence = 0;
         this._sequence = 0;
         this.id = this._lastMsgId = bigInt.zero;
         this.id = this._lastMsgId = bigInt.zero;
         this.msgIds = [];
         this.msgIds = [];
+        this.securityChecks = securityChecks;
         this.reset();
         this.reset();
     }
     }
 
 
@@ -233,7 +236,10 @@ export class MTProtoState {
         }
         }
 
 
         const remoteMsgId = reader.readLong();
         const remoteMsgId = reader.readLong();
-        if (this.msgIds.includes(remoteMsgId.toString())) {
+        if (
+            this.msgIds.includes(remoteMsgId.toString()) &&
+            this.securityChecks
+        ) {
             throw new SecurityError("Duplicate msgIds");
             throw new SecurityError("Duplicate msgIds");
         }
         }
         if (this.msgIds.length > 500) {
         if (this.msgIds.length > 500) {

+ 0 - 1
gramjs/network/connection/Connection.ts

@@ -88,7 +88,6 @@ class Connection {
     async send(data: Buffer) {
     async send(data: Buffer) {
         if (!this._connected) {
         if (!this._connected) {
             // this will stop the current loop
             // this will stop the current loop
-            // @ts-ignore
             await this._sendArray.push(undefined);
             await this._sendArray.push(undefined);
             throw new Error("Not connected");
             throw new Error("Not connected");
         }
         }

+ 2 - 1
gramjs/tl/AllTLObjects.ts

@@ -1,6 +1,7 @@
+export const LAYER = 137;
+
 import { Api } from "./";
 import { Api } from "./";
 
 
-export const LAYER = 137;
 const tlobjects: any = {};
 const tlobjects: any = {};
 
 
 for (const tl of Object.values(Api)) {
 for (const tl of Object.values(Api)) {

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
 {
   "name": "telegram",
   "name": "telegram",
-  "version": "2.4.3",
+  "version": "2.4.5",
   "lockfileVersion": 2,
   "lockfileVersion": 2,
   "requires": true,
   "requires": true,
   "packages": {
   "packages": {
     "": {
     "": {
       "name": "telegram",
       "name": "telegram",
-      "version": "2.4.3",
+      "version": "2.4.5",
       "license": "MIT",
       "license": "MIT",
       "dependencies": {
       "dependencies": {
         "@cryptography/aes": "^0.1.1",
         "@cryptography/aes": "^0.1.1",

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "telegram",
   "name": "telegram",
-  "version": "2.4.3",
+  "version": "2.4.5",
   "description": "NodeJS/Browser MTProto API Telegram client library,",
   "description": "NodeJS/Browser MTProto API Telegram client library,",
   "main": "index.js",
   "main": "index.js",
   "types": "index.d.ts",
   "types": "index.d.ts",