diff --git a/pyrogram/client.py b/pyrogram/client.py index 84a9bb7410..15a9f5347f 100644 --- a/pyrogram/client.py +++ b/pyrogram/client.py @@ -442,24 +442,70 @@ async def authorize(self) -> User: else: break - sent_code_descriptions = { - enums.SentCodeType.APP: "Telegram app", - enums.SentCodeType.CALL: "phone call", - enums.SentCodeType.FLASH_CALL: "phone flash call", - enums.SentCodeType.MISSED_CALL: "", - enums.SentCodeType.SMS: "SMS", - enums.SentCodeType.FRAGMENT_SMS: "Fragment SMS", - enums.SentCodeType.FIREBASE_SMS: "SMS after Firebase attestation", - enums.SentCodeType.EMAIL_CODE: "email", - enums.SentCodeType.SETUP_EMAIL_REQUIRED: "add and verify email required", - } - - print(f"The confirmation code has been sent via {sent_code_descriptions[sent_code.type]}") + if sent_code.type == enums.SentCodeType.SETUP_EMAIL_REQUIRED: + print("Setup email required for authorization") + + while True: + try: + while True: + email = await ainput("Enter setup email: ", loop=self.loop) + + if not email: + continue + + confirm = await ainput(f'Is "{email}" correct? (y/N): ', loop=self.loop) + + if confirm.lower() == "y": + break + + await self.invoke( + raw.functions.account.SendVerifyEmailCode( + purpose=raw.types.EmailVerifyPurposeLoginSetup( + phone_number=self.phone_number, + phone_code_hash=sent_code.phone_code_hash, + ), + email=email, + ) + ) + + email_code = await ainput("Enter confirmation code received in setup email: ", loop=self.loop) + + email_sent_code = await self.invoke( + raw.functions.account.VerifyEmail( + purpose=raw.types.EmailVerifyPurposeLoginSetup( + phone_number=self.phone_number, + phone_code_hash=sent_code.phone_code_hash, + ), + verification=raw.types.EmailVerificationCode(code=email_code), + ) + ) + + if isinstance(email_sent_code, raw.types.account.EmailVerifiedLogin): + sent_code = types.SentCode._parse(email_sent_code.sent_code) + except BadRequest as e: + print(e.MESSAGE) + self.phone_number = None + self.bot_token = None + else: + break + else: + sent_code_descriptions = { + enums.SentCodeType.APP: "Telegram app", + enums.SentCodeType.CALL: "phone call", + enums.SentCodeType.FLASH_CALL: "phone flash call", + enums.SentCodeType.MISSED_CALL: "", + enums.SentCodeType.SMS: "SMS", + enums.SentCodeType.FRAGMENT_SMS: "Fragment SMS", + enums.SentCodeType.FIREBASE_SMS: "SMS after Firebase attestation", + enums.SentCodeType.EMAIL_CODE: "email", + enums.SentCodeType.SETUP_EMAIL_REQUIRED: "add and verify email required", + } + + print(f"The confirmation code has been sent via {sent_code_descriptions[sent_code.type]}") while True: if not self.phone_code: self.phone_code = await ainput("Enter confirmation code: ") - try: signed_in = await self.sign_in(self.phone_number, sent_code.phone_code_hash, self.phone_code) except BadRequest as e: diff --git a/pyrogram/types/authorization/sent_code.py b/pyrogram/types/authorization/sent_code.py index 2b29bb3af4..946b67230f 100644 --- a/pyrogram/types/authorization/sent_code.py +++ b/pyrogram/types/authorization/sent_code.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from pyrogram import raw, enums +from pyrogram.errors import Unauthorized from ..object import Object @@ -53,10 +54,17 @@ def __init__( self.timeout = timeout @staticmethod - def _parse(sent_code: raw.types.auth.SentCode) -> "SentCode": - return SentCode( - type=enums.SentCodeType(type(sent_code.type)), - phone_code_hash=sent_code.phone_code_hash, - next_type=enums.NextCodeType(type(sent_code.next_type)) if sent_code.next_type else None, - timeout=sent_code.timeout - ) + def _parse(sent_code: raw.base.auth.SentCode) -> "SentCode": + if isinstance(sent_code, raw.types.auth.SentCodePaymentRequired): + # TODO: raw.functions.auth.CheckPaidAuth + raise Unauthorized( + f"You need to pay {sent_code.amount}{sent_code.currency} or contact {sent_code.support_email_subject} ({sent_code.support_email_address}) which is currently not supported by Pyrogram." + ) + + if isinstance(sent_code, raw.types.auth.SentCode): + return SentCode( + type=enums.SentCodeType(type(sent_code.type)), + phone_code_hash=sent_code.phone_code_hash, + next_type=enums.NextCodeType(type(sent_code.next_type)) if sent_code.next_type else None, + timeout=sent_code.timeout + )