Przeglądaj źródła

Fix types with no args
Add easier sign in process

painor 5 lat temu
rodzic
commit
48ff535d99

+ 136 - 5
gramjs/client/TelegramClient.js

@@ -9,6 +9,7 @@ const os = require('os')
 const { GetConfigRequest } = require('../tl/functions/help')
 const { LAYER } = require('../tl/AllTLObjects')
 const { functions, types } = require('../tl')
+const { computeCheck } = require('../Password')
 const MTProtoSender = require('../network/MTProtoSender')
 const { ConnectionTCPFull } = require('../network/connection/TCPFull')
 const DEFAULT_DC_ID = 4
@@ -259,6 +260,100 @@ class TelegramClient {
         return me
     }
 
+    async start(args = {
+        phone: null,
+        code: null,
+        password: null,
+        botToken: null,
+        forceSMS: null,
+        firstName: null,
+        lastName: null,
+        maxAttempts: 5,
+    }) {
+
+        if (!this.isConnected()) {
+            await this.connect()
+        }
+        if (await this.isUserAuthorized()) {
+            return this
+        }
+        if (!args.botToken) {
+            args.phone = utils.parsePhone(args.phone) || args.phone
+        }
+        if (args.botToken) {
+            await this.signIn({
+                botToken: args.botToken,
+            })
+            return this
+        }
+
+        let me
+        let attempts = 0
+        let twoStepDetected = false
+
+        await this.sendCodeRequest(args.phone, args.forceSMS)
+        let signUp = false
+        while (attempts < args.maxAttempts) {
+            try {
+                const value = args.code
+                if (!value) {
+                    throw new errors.PhoneCodeEmptyError({
+                        request: null,
+                    })
+                }
+                if (signUp) {
+                    me = await this.signUp({
+                        code: value,
+                        firstName: args.firstName,
+                        lastName: args.lastName,
+                    })
+                } else {
+                    // this throws SessionPasswordNeededError if 2FA enabled
+                    me = await this.signIn({
+                        phone: args.phone,
+                        code: value,
+                    })
+                }
+                break
+            } catch (e) {
+                if (e instanceof errors.SessionPasswordNeededError) {
+                    twoStepDetected = true
+                    break
+                } else if (e instanceof errors.PhoneNumberOccupiedError) {
+                    signUp = true
+
+                } else if (e instanceof errors.PhoneNumberUnoccupiedError) {
+                    signUp = true
+
+                } else if (e instanceof errors.PhoneCodeEmptyError ||
+                    e instanceof errors.PhoneCodeExpiredError ||
+                    e instanceof errors.PhoneCodeHashEmptyError ||
+                    e instanceof errors.PhoneCodeInvalidError) {
+                    console.log('Invalid code. Please try again.')
+                } else {
+                    throw e
+                }
+            }
+            attempts++
+        }
+        if (attempts >= args.maxAttempts) {
+            throw new Error(`${args.maxAttempts} consecutive sign-in attempts failed. Aborting`)
+        }
+        if (twoStepDetected) {
+            if (!args.password) {
+                throw new Error('Two-step verification is enabled for this account. ' +
+                    'Please provide the \'password\' argument to \'start()\'.')
+            }
+            me = await this.signIn({
+                phone: args.phone,
+                password: args.password,
+            })
+        }
+        const name = utils.getDisplayName(me)
+        console.log('Signed in successfully as', name)
+        return this
+    }
+
     async signIn(args = {
         phone: null,
         code: null,
@@ -270,7 +365,7 @@ class TelegramClient {
         if (args.phone && !args.code && !args.password) {
             return await this.sendCodeRequest(args.phone)
         } else if (args.code) {
-            const { phone, phoneCodeHash } =
+            const [phone, phoneCodeHash] =
                 this._parsePhoneAndHash(args.phone, args.phoneCodeHash)
             // May raise PhoneCodeEmptyError, PhoneCodeExpiredError,
             // PhoneCodeHashEmptyError or PhoneCodeInvalidError.
@@ -278,8 +373,9 @@ class TelegramClient {
                 phone, phoneCodeHash, args.code.toString()))
         } else if (args.password) {
             const pwd = await this.invoke(new functions.account.GetPasswordRequest())
-            result = await this.invoke(new functions.auth.CheckPasswordRequest(
-                pwdMod.computeCheck(pwd, args.password),
+            result = await this.invoke(new functions.auth.CheckPasswordRequest({
+                    password: computeCheck(pwd, args.password),
+                },
             ))
         } else if (args.botToken) {
             result = await this.invoke(new functions.auth.ImportBotAuthorizationRequest(
@@ -297,6 +393,20 @@ class TelegramClient {
         return this._onLogin(result.user)
     }
 
+
+    _parsePhoneAndHash(phone, phoneHash) {
+        phone = utils.parsePhone(phone) || this._phone
+        if (!phone) {
+            throw new Error('Please make sure to call send_code_request first.')
+        }
+        phoneHash = phoneHash || this._phoneCodeHash[phone]
+        if (!phoneHash) {
+            throw new Error('You also need to provide a phone_code_hash.')
+        }
+
+        return [phone, phoneHash]
+    }
+
     // endregion
     async isUserAuthorized() {
         if (!this._authorized) {
@@ -341,8 +451,15 @@ class TelegramClient {
                 }
                 throw e
             }
-            this._tos = result.termsOfService
-            this._phoneCodeHash[phone] = phoneHash = result.phoneCodeHash
+
+            // If we already sent a SMS, do not resend the code (hash may be empty)
+            if (result.type instanceof types.auth.SentCodeTypeSms) {
+                forceSMS = false
+            }
+            console.log('got result', result)
+            if (result.phoneCodeHash) {
+                this._phoneCodeHash[phone] = phoneHash = result.phoneCodeHash
+            }
         } else {
             forceSMS = true
         }
@@ -642,6 +759,20 @@ class TelegramClient {
             }
         }
     }
+
+    isConnected() {
+        if (this._sender) {
+            if (this._sender.isConnected()) {
+                return true
+            }
+        }
+        return false
+
+    }
+
+    async signUp() {
+
+    }
 }
 
 module.exports = TelegramClient

+ 0 - 2
gramjs/network/MTProtoSender.js

@@ -374,11 +374,9 @@ class MTProtoSender {
      * @private
      */
     async _processMessage(message) {
-        console.log('got message : ', message)
         this._pending_ack.add(message.msgId)
         // eslint-disable-next-line require-atomic-updates
         message.obj = await message.obj
-        console.log('obj is ', message.obj)
         let handler = this._handlers[message.obj.CONSTRUCTOR_ID]
         if (!handler) {
             handler = this._handleUpdate.bind(this)

+ 1 - 1
gramjs_generator/generators/tlobject.js

@@ -299,7 +299,7 @@ const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
     builder.writeln('*/')
     builder.writeln(`constructor(args) {`)
     builder.writeln(`super();`)
-
+    builder.writeln(`args = args || {}`)
     // Class-level variable to store its Telegram's constructor ID
     builder.writeln(`this.CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`)
     builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`)