82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
package rpc
|
|
|
|
import (
|
|
"encoding/base64"
|
|
|
|
"github.com/gotd/td/tg"
|
|
|
|
"telesrv/internal/domain"
|
|
)
|
|
|
|
// decodePasskeyID 容忍有/无填充地 base64url 解码 credential id(取第一个可解的非空值)。
|
|
func decodePasskeyID(vals ...string) ([]byte, bool) {
|
|
for _, v := range vals {
|
|
if v == "" {
|
|
continue
|
|
}
|
|
if b, err := base64.RawURLEncoding.DecodeString(v); err == nil && len(b) > 0 {
|
|
return b, true
|
|
}
|
|
if b, err := base64.URLEncoding.DecodeString(v); err == nil && len(b) > 0 {
|
|
return b, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func passkeyPublicKeyCredential(cred tg.InputPasskeyCredentialClass) (*tg.InputPasskeyCredentialPublicKey, bool) {
|
|
pk, ok := cred.(*tg.InputPasskeyCredentialPublicKey)
|
|
return pk, ok
|
|
}
|
|
|
|
// passkeyLoginFromCredential 从 inputPasskeyCredentialPublicKey 提取登录断言字段。
|
|
func passkeyLoginFromCredential(cred tg.InputPasskeyCredentialClass) (credID []byte, login *tg.InputPasskeyResponseLogin, ok bool) {
|
|
pk, ok := passkeyPublicKeyCredential(cred)
|
|
if !ok {
|
|
return nil, nil, false
|
|
}
|
|
login, ok = pk.Response.(*tg.InputPasskeyResponseLogin)
|
|
if !ok {
|
|
return nil, nil, false
|
|
}
|
|
credID, ok = decodePasskeyID(pk.RawID, pk.ID)
|
|
if !ok {
|
|
return nil, nil, false
|
|
}
|
|
return credID, login, true
|
|
}
|
|
|
|
// passkeyRegisterFromCredential 从 inputPasskeyCredentialPublicKey 提取注册 attestation 字段。
|
|
func passkeyRegisterFromCredential(cred tg.InputPasskeyCredentialClass) (credID []byte, reg *tg.InputPasskeyResponseRegister, ok bool) {
|
|
pk, ok := passkeyPublicKeyCredential(cred)
|
|
if !ok {
|
|
return nil, nil, false
|
|
}
|
|
reg, ok = pk.Response.(*tg.InputPasskeyResponseRegister)
|
|
if !ok {
|
|
return nil, nil, false
|
|
}
|
|
credID, ok = decodePasskeyID(pk.RawID, pk.ID)
|
|
if !ok {
|
|
return nil, nil, false
|
|
}
|
|
return credID, reg, true
|
|
}
|
|
|
|
// tgPasskey 把领域凭据投影为 tg.Passkey(ID 用 base64url)。
|
|
func tgPasskey(c domain.PasskeyCredential) tg.Passkey {
|
|
return tg.Passkey{
|
|
ID: base64.RawURLEncoding.EncodeToString(c.CredentialID),
|
|
Name: c.Name,
|
|
Date: int(c.CreatedAt),
|
|
LastUsageDate: int(c.LastUsedAt),
|
|
}
|
|
}
|
|
|
|
func tgPasskeys(creds []domain.PasskeyCredential) []tg.Passkey {
|
|
out := make([]tg.Passkey, 0, len(creds))
|
|
for _, c := range creds {
|
|
out = append(out, tgPasskey(c))
|
|
}
|
|
return out
|
|
}
|