rpc: add android login startup compat
(cherry picked from commit 53904e72f7c3b96e6ae5e24196d0e551fa8aebce)
This commit is contained in:
parent
82dd2996e6
commit
294e994272
7 changed files with 127 additions and 3 deletions
|
|
@ -96,6 +96,7 @@ status 取值:done(真实实现) / stub(兼容响应) / todo(已发现未实
|
||||||
| auth.bindTempAuthKey | done | real-validated | 校验 encrypted bind_auth_key_inner(nonce/temp key/perm key/session/expires_at)后记录 temp_auth_key_bindings;后续 temp auth_key RPC 会解析为 perm auth_key 身份,并刷新 active session 的业务 auth_key_id / user_id 缓存 |
|
| auth.bindTempAuthKey | done | real-validated | 校验 encrypted bind_auth_key_inner(nonce/temp key/perm key/session/expires_at)后记录 temp_auth_key_bindings;后续 temp auth_key RPC 会解析为 perm auth_key 身份,并刷新 active session 的业务 auth_key_id / user_id 缓存 |
|
||||||
| auth.exportLoginToken / auth.importLoginToken | stub | tdesktop-qr-placeholder | TDesktop QR 登录页轮询;当前单 DC 主路径只支持手机号登录,返回短期 auth.loginToken 避免未实现噪声;`auth.acceptLoginToken` 显式返回 `AUTH_TOKEN_INVALID`,不伪造跨设备 QR 授权 |
|
| auth.exportLoginToken / auth.importLoginToken | stub | tdesktop-qr-placeholder | TDesktop QR 登录页轮询;当前单 DC 主路径只支持手机号登录,返回短期 auth.loginToken 避免未实现噪声;`auth.acceptLoginToken` 显式返回 `AUTH_TOKEN_INVALID`,不伪造跨设备 QR 授权 |
|
||||||
| auth.exportAuthorization / auth.importAuthorization / auth.dropTempAuthKeys | stub | single-dc-bounded | 单 DC 当前不做跨 DC authorization handoff;export/import 返回 `DC_ID_INVALID`,dropTempAuthKeys 返回成功避免旧 temp key 清理路径噪声 |
|
| auth.exportAuthorization / auth.importAuthorization / auth.dropTempAuthKeys | stub | single-dc-bounded | 单 DC 当前不做跨 DC authorization handoff;export/import 返回 `DC_ID_INVALID`,dropTempAuthKeys 返回成功避免旧 temp key 清理路径噪声 |
|
||||||
|
| auth.initPasskeyLogin | stub | empty-options | DrKLO Android 手机号页会后台预取 passkey 登录;当前不接 passkey,返回空 `auth.passkeyLoginOptions` 避免反复 NOT_IMPLEMENTED |
|
||||||
| auth.sendCode / auth.resendCode / auth.cancelCode | done | dev-code | 开发固定验证码,phone_code_hash 存 Redis CodeStore;手机号统一规范为纯数字;resend 会校验并失效旧 hash 后生成新 hash,cancel 会删除 pending code |
|
| auth.sendCode / auth.resendCode / auth.cancelCode | done | dev-code | 开发固定验证码,phone_code_hash 存 Redis CodeStore;手机号统一规范为纯数字;resend 会校验并失效旧 hash 后生成新 hash,cancel 会删除 pending code |
|
||||||
| auth.signIn | done | real+2fa-gate | 校验码;兼容 TDesktop sendCode 后 signIn 使用 DigitsOnly(phone);无 2FA 时登录成功绑定在线 session 的 user_id,写入并延迟推送 777000 官方登录消息 updateNewMessage,同时向其它在线 session 推送新登录 updateServiceNotification;账号已启用 2FA 时返回 `SESSION_PASSWORD_NEEDED` 并等待 `auth.checkPassword` |
|
| auth.signIn | done | real+2fa-gate | 校验码;兼容 TDesktop sendCode 后 signIn 使用 DigitsOnly(phone);无 2FA 时登录成功绑定在线 session 的 user_id,写入并延迟推送 777000 官方登录消息 updateNewMessage,同时向其它在线 session 推送新登录 updateServiceNotification;账号已启用 2FA 时返回 `SESSION_PASSWORD_NEEDED` 并等待 `auth.checkPassword` |
|
||||||
| auth.signUp | done | real | 建 user + 绑定 authorization;登录成功绑定在线 session 的 user_id,写入并延迟推送 777000 官方登录消息 updateNewMessage |
|
| auth.signUp | done | real | 建 user + 绑定 authorization;登录成功绑定在线 session 的 user_id,写入并延迟推送 777000 官方登录消息 updateNewMessage |
|
||||||
|
|
@ -399,9 +400,9 @@ outbox 多 worker 并发 + 发送事务乱序提交 → **主动推送可能乱
|
||||||
|
|
||||||
| method | status | behavior | note |
|
| method | status | behavior | note |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| langpack.getLangPack | done | real | PG-backed;启动 seed `tdesktop_en/zh-hans_v12000000.strings` |
|
| langpack.getLangPack | done | real+legacy-adapter | PG-backed;启动 seed `tdesktop_en/zh-hans_v12000000.strings`;DrKLO Android legacy `#9ab5c58e lang_code:string` 由 RPC edge 补 `lang_pack` 后复用当前实现 |
|
||||||
| langpack.getDifference | done | real | 按 version 返回语言包差异;当前 seed 同版本全量 |
|
| langpack.getDifference | done | real | 按 version 返回语言包差异;当前 seed 同版本全量 |
|
||||||
| langpack.getStrings | done | real | 按 key 查询 PG 中的语言包字符串 |
|
| langpack.getStrings | done | real+legacy-adapter | 按 key 查询 PG 中的语言包字符串;DrKLO Android legacy `#2e1ee318 lang_code:string keys:Vector<string>` 由 RPC edge 补 `lang_pack`,keys 上限 512 |
|
||||||
| langpack.getLanguages | done | compat-static | Layer 225 `#42c6978f` 已注册;DrKLO Android 仍会发 legacy `#800fd57d` 无参版本,RPC edge 显式 adapter 后返回语言列表 |
|
| langpack.getLanguages | done | compat-static | Layer 225 `#42c6978f` 已注册;DrKLO Android 仍会发 legacy `#800fd57d` 无参版本,RPC edge 显式 adapter 后返回语言列表 |
|
||||||
|
|
||||||
## Files / Media / Photos
|
## Files / Media / Photos
|
||||||
|
|
|
||||||
|
|
@ -608,6 +608,7 @@ func clientMessageNeedsAck(typeID uint32) bool {
|
||||||
case proto.MessageContainerTypeID,
|
case proto.MessageContainerTypeID,
|
||||||
mt.MsgsAckTypeID,
|
mt.MsgsAckTypeID,
|
||||||
mt.PingDelayDisconnectRequestTypeID,
|
mt.PingDelayDisconnectRequestTypeID,
|
||||||
|
mt.DestroySessionRequestTypeID,
|
||||||
mt.HTTPWaitRequestTypeID,
|
mt.HTTPWaitRequestTypeID,
|
||||||
mt.BadMsgNotificationTypeID,
|
mt.BadMsgNotificationTypeID,
|
||||||
mt.BadServerSaltTypeID,
|
mt.BadServerSaltTypeID,
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@ func (r *Router) registerAuth(d *tg.ServerDispatcher) {
|
||||||
d.OnAuthDropTempAuthKeys(func(ctx context.Context, exceptauthkeys []int64) (bool, error) {
|
d.OnAuthDropTempAuthKeys(func(ctx context.Context, exceptauthkeys []int64) (bool, error) {
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
|
d.OnAuthInitPasskeyLogin(func(ctx context.Context, req *tg.AuthInitPasskeyLoginRequest) (*tg.AuthPasskeyLoginOptions, error) {
|
||||||
|
return &tg.AuthPasskeyLoginOptions{Options: tg.DataJSON{Data: "{}"}}, nil
|
||||||
|
})
|
||||||
d.OnAuthSendCode(r.onAuthSendCode)
|
d.OnAuthSendCode(r.onAuthSendCode)
|
||||||
d.OnAuthResendCode(r.onAuthResendCode)
|
d.OnAuthResendCode(r.onAuthResendCode)
|
||||||
d.OnAuthCancelCode(r.onAuthCancelCode)
|
d.OnAuthCancelCode(r.onAuthCancelCode)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,12 @@ func (r *Router) dispatchCompat(ctx context.Context, b *bin.Buffer, id uint32) (
|
||||||
)
|
)
|
||||||
|
|
||||||
switch id {
|
switch id {
|
||||||
|
case legacyLangpackGetLangPackTypeID:
|
||||||
|
name = "langpack.getLangPack#9ab5c58e"
|
||||||
|
enc, err = r.handleLegacyLangpackGetLangPack(ctx, b)
|
||||||
|
case legacyLangpackGetStringsTypeID:
|
||||||
|
name = "langpack.getStrings#2e1ee318"
|
||||||
|
enc, err = r.handleLegacyLangpackGetStrings(ctx, b)
|
||||||
case legacyLangpackGetLanguagesTypeID:
|
case legacyLangpackGetLanguagesTypeID:
|
||||||
name = "langpack.getLanguages#800fd57d"
|
name = "langpack.getLanguages#800fd57d"
|
||||||
enc, err = r.handleLegacyLangpackGetLanguages(ctx, b)
|
enc, err = r.handleLegacyLangpackGetLanguages(ctx, b)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,13 @@ import (
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
)
|
)
|
||||||
|
|
||||||
const legacyLangpackGetLanguagesTypeID uint32 = 0x800fd57d
|
const (
|
||||||
|
legacyLangpackGetLangPackTypeID uint32 = 0x9ab5c58e
|
||||||
|
legacyLangpackGetStringsTypeID uint32 = 0x2e1ee318
|
||||||
|
legacyLangpackGetLanguagesTypeID uint32 = 0x800fd57d
|
||||||
|
|
||||||
|
maxLegacyLangpackStringKeys = 512
|
||||||
|
)
|
||||||
|
|
||||||
// registerLangpack 注册 langpack.* RPC handler。
|
// registerLangpack 注册 langpack.* RPC handler。
|
||||||
func (r *Router) registerLangpack(d *tg.ServerDispatcher) {
|
func (r *Router) registerLangpack(d *tg.ServerDispatcher) {
|
||||||
|
|
@ -47,6 +53,59 @@ func (r *Router) registerLangpack(d *tg.ServerDispatcher) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Router) handleLegacyLangpackGetLangPack(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||||
|
if err := b.ConsumeID(legacyLangpackGetLangPackTypeID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
langCode, err := b.String()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
langPack := langPackFromClient(ctx)
|
||||||
|
if r.deps.LangPack == nil {
|
||||||
|
return &tg.LangPackDifference{LangCode: langCode}, nil
|
||||||
|
}
|
||||||
|
pack, err := r.deps.LangPack.GetLangPack(ctx, langPack, langCode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, internalErr()
|
||||||
|
}
|
||||||
|
return tgLangPackDifference(pack), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Router) handleLegacyLangpackGetStrings(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||||
|
if err := b.ConsumeID(legacyLangpackGetStringsTypeID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
langCode, err := b.String()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
headerLen, err := b.VectorHeader()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if headerLen > maxLegacyLangpackStringKeys {
|
||||||
|
return nil, limitInvalidErr()
|
||||||
|
}
|
||||||
|
keys := make([]string, 0, headerLen)
|
||||||
|
for i := 0; i < headerLen; i++ {
|
||||||
|
key, err := b.String()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
langPack := langPackFromClient(ctx)
|
||||||
|
if r.deps.LangPack == nil {
|
||||||
|
return &tg.LangPackStringClassVector{}, nil
|
||||||
|
}
|
||||||
|
pack, err := r.deps.LangPack.GetStrings(ctx, langPack, langCode, keys)
|
||||||
|
if err != nil {
|
||||||
|
return nil, internalErr()
|
||||||
|
}
|
||||||
|
return &tg.LangPackStringClassVector{Elems: tgLangPackStrings(pack.Strings)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Router) handleLegacyLangpackGetLanguages(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
func (r *Router) handleLegacyLangpackGetLanguages(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||||
if err := b.ConsumeID(legacyLangpackGetLanguagesTypeID); err != nil {
|
if err := b.ConsumeID(legacyLangpackGetLanguagesTypeID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,51 @@ func TestLangpackGetLanguagesCurrentAndLegacy(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLegacyLangpackGetLangPack(t *testing.T) {
|
||||||
|
r := New(Config{DC: 2, IP: "127.0.0.1", Port: 2398}, Deps{}, zaptest.NewLogger(t), clock.System)
|
||||||
|
|
||||||
|
var in bin.Buffer
|
||||||
|
in.PutID(legacyLangpackGetLangPackTypeID)
|
||||||
|
in.PutString("en")
|
||||||
|
enc, err := r.Dispatch(androidClientContext(), [8]byte{}, 0, &in)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("dispatch legacy langpack.getLangPack: %v", err)
|
||||||
|
}
|
||||||
|
var out bin.Buffer
|
||||||
|
if err := enc.Encode(&out); err != nil {
|
||||||
|
t.Fatalf("encode response: %v", err)
|
||||||
|
}
|
||||||
|
var diff tg.LangPackDifference
|
||||||
|
if err := diff.Decode(&out); err != nil {
|
||||||
|
t.Fatalf("decode response: %v", err)
|
||||||
|
}
|
||||||
|
if diff.LangCode != "en" {
|
||||||
|
t.Fatalf("difference = %+v, want lang_code=en", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLegacyLangpackGetStrings(t *testing.T) {
|
||||||
|
r := New(Config{DC: 2, IP: "127.0.0.1", Port: 2398}, Deps{}, zaptest.NewLogger(t), clock.System)
|
||||||
|
|
||||||
|
var in bin.Buffer
|
||||||
|
in.PutID(legacyLangpackGetStringsTypeID)
|
||||||
|
in.PutString("en")
|
||||||
|
in.PutVectorHeader(1)
|
||||||
|
in.PutString("lng_intro_about")
|
||||||
|
enc, err := r.Dispatch(androidClientContext(), [8]byte{}, 0, &in)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("dispatch legacy langpack.getStrings: %v", err)
|
||||||
|
}
|
||||||
|
var out bin.Buffer
|
||||||
|
if err := enc.Encode(&out); err != nil {
|
||||||
|
t.Fatalf("encode response: %v", err)
|
||||||
|
}
|
||||||
|
var strings tg.LangPackStringClassVector
|
||||||
|
if err := strings.Decode(&out); err != nil {
|
||||||
|
t.Fatalf("decode response: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func assertLangpackLanguages(t *testing.T, r *Router, ctx context.Context, in *bin.Buffer) {
|
func assertLangpackLanguages(t *testing.T, r *Router, ctx context.Context, in *bin.Buffer) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
enc, err := r.Dispatch(ctx, [8]byte{}, 0, in)
|
enc, err := r.Dispatch(ctx, [8]byte{}, 0, in)
|
||||||
|
|
@ -52,3 +97,11 @@ func assertLangpackLanguages(t *testing.T, r *Router, ctx context.Context, in *b
|
||||||
t.Fatalf("languages = %+v, want English entry", langs.Elems)
|
t.Fatalf("languages = %+v, want English entry", langs.Elems)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func androidClientContext() context.Context {
|
||||||
|
return WithClientInfo(context.Background(), ClientInfo{
|
||||||
|
DeviceModel: "Android",
|
||||||
|
AppVersion: "12.7.3",
|
||||||
|
LangCode: "en",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -401,6 +401,7 @@ func TestTDesktopStartupRPCsEncode(t *testing.T) {
|
||||||
{name: "help.getPromoData", req: &tg.HelpGetPromoDataRequest{}},
|
{name: "help.getPromoData", req: &tg.HelpGetPromoDataRequest{}},
|
||||||
{name: "help.getTermsOfServiceUpdate", req: &tg.HelpGetTermsOfServiceUpdateRequest{}},
|
{name: "help.getTermsOfServiceUpdate", req: &tg.HelpGetTermsOfServiceUpdateRequest{}},
|
||||||
{name: "help.getPremiumPromo", req: &tg.HelpGetPremiumPromoRequest{}},
|
{name: "help.getPremiumPromo", req: &tg.HelpGetPremiumPromoRequest{}},
|
||||||
|
{name: "auth.initPasskeyLogin", req: &tg.AuthInitPasskeyLoginRequest{APIID: 4, APIHash: "test"}},
|
||||||
{name: "account.getPassword", req: &tg.AccountGetPasswordRequest{}},
|
{name: "account.getPassword", req: &tg.AccountGetPasswordRequest{}},
|
||||||
{name: "account.getNotifySettings", req: &tg.AccountGetNotifySettingsRequest{Peer: &tg.InputNotifyUsers{}}},
|
{name: "account.getNotifySettings", req: &tg.AccountGetNotifySettingsRequest{Peer: &tg.InputNotifyUsers{}}},
|
||||||
{name: "account.resetNotifySettings", req: &tg.AccountResetNotifySettingsRequest{}},
|
{name: "account.resetNotifySettings", req: &tg.AccountResetNotifySettingsRequest{}},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue