Bläddra i källkod

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

painor 3 år sedan
förälder
incheckning
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),
                 isMainSender: true,
                 client: this,
+                securityChecks: this._securityChecks,
             });
         }
         // set defaults vars
@@ -1361,6 +1362,7 @@ export class TelegramClient extends TelegramBaseClient {
 
         this.session.setAuthKey(this._sender.authKey);
         this._initRequest.query = new Api.help.GetConfig();
+        this._log.info(`Using LAYER ${LAYER} for initial connect`);
         await this._sender.send(
             new Api.InvokeWithLayer({
                 layer: LAYER,

+ 12 - 5
gramjs/client/telegramBaseClient.ts

@@ -113,6 +113,10 @@ export interface TelegramClientParams {
      * Limits how many downloads happen at the same time.
      */
     maxConcurrentDownloads?: number;
+    /**
+     * Whether to check for tampering in messages or not.
+     */
+    securityChecks?: boolean;
 }
 
 const clientParamsDefault = {
@@ -131,6 +135,7 @@ const clientParamsDefault = {
     appVersion: "",
     langCode: "en",
     systemLangCode: "en",
+    _securityChecks: true,
     useWSS:
         typeof window !== "undefined"
             ? window.location.protocol == "https:"
@@ -205,6 +210,7 @@ export abstract class TelegramBaseClient {
     _destroyed: boolean;
     protected _proxy?: ProxyInterface;
     _semaphore: Semaphore;
+    _securityChecks: boolean;
     constructor(
         session: string | Session,
         apiId: number,
@@ -275,6 +281,7 @@ export abstract class TelegramBaseClient {
         this._bot = undefined;
         this._selfInputPeer = undefined;
         this.useWSS = clientParams.useWSS!;
+        this._securityChecks = !!clientParams.securityChecks;
         if (this.useWSS && this._proxy) {
             throw new Error(
                 "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
-     * @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() {
+        this._destroyed = true;
         await Promise.all([
             this.disconnect(),
-            this.session.delete(),
             ...Object.values(this._borrowedSenderPromises).map(
                 (promise: any) => {
                     return promise.then((sender: any) => sender.disconnect());
@@ -404,7 +409,7 @@ export abstract class TelegramBaseClient {
 
                 if (this.session.dcId !== dcId && !sender._authenticated) {
                     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(
                         new Api.auth.ExportAuthorization({ dcId: dcId })
@@ -413,6 +418,7 @@ export abstract class TelegramBaseClient {
                         id: auth.id,
                         bytes: auth.bytes,
                     });
+
                     const req = new Api.InvokeWithLayer({
                         layer: LAYER,
                         query: this._initRequest,
@@ -502,6 +508,7 @@ export abstract class TelegramBaseClient {
             isMainSender: dcId === this.session.dcId,
             onConnectionBreak: this._cleanupExportedSender.bind(this),
             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) {
             continue;
         }
+        if (client._destroyed) {
+            return;
+        }
 
         try {
             await attempts(

+ 13 - 2
gramjs/network/MTProtoSender.ts

@@ -47,6 +47,7 @@ interface DEFAULT_OPTIONS {
     senderCallback?: any;
     client: TelegramClient;
     onConnectionBreak?: CallableFunction;
+    securityChecks: boolean;
 }
 
 export class MTProtoSender {
@@ -62,6 +63,7 @@ export class MTProtoSender {
         isMainSender: null,
         senderCallback: null,
         onConnectionBreak: undefined,
+        securityChecks: true,
     };
     private _connection?: Connection;
     private readonly _log: Logger;
@@ -95,13 +97,17 @@ export class MTProtoSender {
     userDisconnected: boolean;
     isConnecting: boolean;
     _authenticated: boolean;
+    private _securityChecks: boolean;
 
     /**
      * @param authKey
      * @param opts
      */
     constructor(authKey: undefined | AuthKey, opts: DEFAULT_OPTIONS) {
-        const args = { ...MTProtoSender.DEFAULT_OPTIONS, ...opts };
+        const args = {
+            ...MTProtoSender.DEFAULT_OPTIONS,
+            ...opts,
+        };
         this._connection = undefined;
         this._log = args.logger;
         this._dcId = args.dcId;
@@ -116,6 +122,7 @@ export class MTProtoSender {
         this._senderCallback = args.senderCallback;
         this._client = args.client;
         this._onConnectionBreak = args.onConnectionBreak;
+        this._securityChecks = args.securityChecks;
 
         /**
          * 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
          */
         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.

+ 8 - 2
gramjs/network/MTProtoState.ts

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

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

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

+ 2 - 1
gramjs/tl/AllTLObjects.ts

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

+ 2 - 2
package-lock.json

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

+ 1 - 1
package.json

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