owpengram-server/internal/rpc/convert_passkey.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
}