rpc: return PASSWORD_MISSING for channel transfer without 2FA

messages.editChatCreator unconditionally returned PASSWORD_HASH_INVALID for
an account with no cloud password at all. Real Telegram Desktop's transfer-
ownership flow only recognizes the distinct PASSWORD_MISSING error to show
its "enable 2FA first" box; anything else falls through into the real
password-entry flow, which then has nothing to check against and crashes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Astra 2026-09-13 22:07:54 +01:00
parent 61f6685603
commit f823b2cb74
4 changed files with 75 additions and 3 deletions

View file

@ -339,6 +339,20 @@ func (r *Router) onMessagesEditChatCreator(ctx context.Context, req *tg.Messages
if req.Password == nil {
return nil, passwordHashInvalidErr()
}
if r.deps.Account == nil {
return nil, passwordHashInvalidErr()
}
// 转让所有权无条件要求已开启两步验证:先探测账号是否设有密码,
// 让 messages.editChatCreator 的探测请求inputUserEmpty + inputCheckPasswordEmpty
// 拿到 PASSWORD_MISSING 而非 PASSWORD_HASH_INVALID —— 客户端只识别前者来展示
// “请先开启两步验证”提示,否则会误入真实密码校验流程并在没有密码可核对时崩溃。
passwordSettings, err := r.deps.Account.GetPassword(ctx, userID)
if err != nil {
return nil, internalErr()
}
if !passwordSettings.HasPassword {
return nil, passwordMissingErr()
}
if _, ok := req.UserID.(*tg.InputUserEmpty); ok {
return nil, passwordHashInvalidErr()
}
@ -355,9 +369,6 @@ func (r *Router) onMessagesEditChatCreator(ctx context.Context, req *tg.Messages
if target.Bot {
return nil, userIDInvalidErr()
}
if r.deps.Account == nil {
return nil, passwordHashInvalidErr()
}
if err := r.deps.Account.CheckPassword(ctx, userID, domainPasswordCheck(req.Password)); err != nil {
return nil, passwordErr(err)
}