Support for login email registration (still experimental)

This commit is contained in:
Wizou 2022-09-14 18:29:07 +02:00
parent 11a9ca8631
commit 1ed10d99af
3 changed files with 42 additions and 3 deletions

1
FAQ.md
View file

@ -220,6 +220,7 @@ In particular, it will detect and handle automatically and properly the various
* Login not necessary (when a session is resumed with an already logged-in user)
* Logout required (if you want to change the logged-in user)
* 2FA password required (your Config needs to provide "password")
* Email registration procedure required (your Config needs to provide "email", "email_verification_code")
* Account registration/sign-up required (your Config needs to provide "first_name", "last_name")
* Request to resend the verification code through alternate ways like SMS (if your Config answer an empty "verification_code" initially)
* Transient failures, slowness to respond, wrong code/password, checks for encryption key safety, etc..

View file

@ -36,6 +36,8 @@ that will be sent to this user (for example through SMS, Email, or another Teleg
If the verification succeeds but the phone number is unknown to Telegram, the user might be prompted to sign-up
*(register their account by accepting the Terms of Service)* and provide their **first_name** and **last_name**.
If the account already exists and has enabled two-step verification (2FA) a **password** might be required.
In some case, Telegram may request that you associate an **email** with your account for receiving login verification codes,
you may skip this step by leaving **email** empty, otherwise the email address will first receive an **email_verification_code**.
All these login scenarios are handled automatically within the call to `LoginUserIfNeeded`.
After login, you now have access to the **[full range of Telegram Client APIs](https://corefork.telegram.org/methods)**.
@ -149,7 +151,7 @@ See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient
An invalid API request can result in a `RpcException` being raised, reflecting the [error code and status text](https://revgram.github.io/errors.html) of the problem.
The other configuration items that you can override include: **session_pathname, session_key, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, user_id**
The other configuration items that you can override include: **session_pathname, email, email_verification_code, session_key, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, user_id**
Optional API parameters have a default value of `null` when unset. Passing `null` for a required string/array is the same as *empty* (0-length).
Required API parameters/fields can sometimes be set to 0 or `null` when unused (check API documentation or experiment).

View file

@ -126,7 +126,7 @@ namespace WTelegram
"lang_pack" => "",
"lang_code" => CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
"user_id" => "-1",
"verification_code" or "password" => AskConfig(what),
"verification_code" or "email_verification_code" or "password" => AskConfig(what),
_ => null // api_id api_hash phone_number... it's up to you to reply to these correctly
};
@ -940,10 +940,46 @@ namespace WTelegram
Auth_AuthorizationBase authorization = null;
try
{
if (sentCode.type is Auth_SentCodeTypeSetUpEmailRequired setupEmail)
{
Helpers.Log(3, "A login email is required");
var email = _config("email");
if (string.IsNullOrEmpty(email))
sentCode = await this.Auth_ResendCode(phone_number, sentCode.phone_code_hash);
else
{
var purpose = new EmailVerifyPurposeLoginSetup { phone_number = phone_number, phone_code_hash = sentCode.phone_code_hash };
if (email is not "Google" and not "Apple")
{
var sentEmail = await this.Account_SendVerifyEmailCode(purpose, email);
Helpers.Log(3, "An email verification code has been sent to " + sentEmail.email_pattern);
RaiseUpdate(sentEmail);
}
Account_EmailVerified verified = null;
for (int retry = 1; verified == null; retry++)
try
{
var code = await ConfigAsync("email_verification_code");
if (email is "Google")
verified = await this.Account_VerifyEmail(purpose, new EmailVerificationGoogle { token = code });
else if (email is "Apple")
verified = await this.Account_VerifyEmail(purpose, new EmailVerificationApple { token = code });
else
verified = await this.Account_VerifyEmail(purpose, new EmailVerificationCode { code = code });
}
catch (RpcException e) when (e.Code == 400 && e.Message is "CODE_INVALID" or "EMAIL_TOKEN_INVALID")
{
Helpers.Log(4, "Wrong email verification code!");
if (retry == MaxCodePwdAttempts) throw;
}
if (verified is Account_EmailVerifiedLogin verifiedLogin) // (it should always be)
sentCode = verifiedLogin.sent_code;
}
}
resent:
var timeout = DateTime.UtcNow + TimeSpan.FromSeconds(sentCode.timeout);
RaiseUpdate(sentCode);
Helpers.Log(3, $"A verification code has been sent via {sentCode.type.GetType().Name[17..]}");
RaiseUpdate(sentCode);
for (int retry = 1; authorization == null; retry++)
try
{