Retrieve XMPP client features

This commit is contained in:
Bohdan Horbeshko 2025-01-12 22:05:24 -05:00
parent ba8f4c08cf
commit 85485bb147
2 changed files with 75 additions and 16 deletions

View file

@ -48,6 +48,9 @@ type Client struct {
lastMsgIds map[int64]string lastMsgIds map[int64]string
msgHashSeed maphash.Seed msgHashSeed maphash.Seed
XmppClientFeatures map[string]*[]string
XmppClientFeaturesLock sync.Mutex
locks clientLocks locks clientLocks
SendMessageLock sync.Mutex SendMessageLock sync.Mutex
} }
@ -109,20 +112,21 @@ func NewClient(conf config.TelegramConfig, jid string, component *xmpp.Component
} }
return &Client{ return &Client{
parameters: &parameters, parameters: &parameters,
xmpp: component, xmpp: component,
jid: jid, jid: jid,
Session: session, Session: session,
resources: make(map[string]bool), resources: make(map[string]bool),
content: &conf.Content, content: &conf.Content,
cache: cache.NewCache(), cache: cache.NewCache(),
outbox: make(map[string]string), outbox: make(map[string]string),
editOutbox: make(map[string]string), editOutbox: make(map[string]string),
options: options, options: options,
DelayedStatuses: make(map[int64]*DelayedStatus), DelayedStatuses: make(map[int64]*DelayedStatus),
lastMsgHashes: make(map[int64]uint64), lastMsgHashes: make(map[int64]uint64),
lastMsgIds: make(map[int64]string), lastMsgIds: make(map[int64]string),
msgHashSeed: maphash.MakeSeed(), msgHashSeed: maphash.MakeSeed(),
XmppClientFeatures: make(map[string]*[]string),
locks: clientLocks{ locks: clientLocks{
chatMessageLocks: make(map[int64]*sync.Mutex), chatMessageLocks: make(map[int64]*sync.Mutex),
}, },

View file

@ -15,6 +15,7 @@ import (
"dev.narayana.im/narayana/telegabber/xmpp/extensions" "dev.narayana.im/narayana/telegabber/xmpp/extensions"
"dev.narayana.im/narayana/telegabber/xmpp/gateway" "dev.narayana.im/narayana/telegabber/xmpp/gateway"
"github.com/google/uuid"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/soheilhy/args" "github.com/soheilhy/args"
"gosrc.io/xmpp" "gosrc.io/xmpp"
@ -40,7 +41,7 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
} }
log.Debugf("%#v", iq) log.Debugf("%#v", iq)
if iq.Type == "get" { if iq.Type == stanza.IQTypeGet {
_, ok := iq.Payload.(*extensions.IqVcardTemp) _, ok := iq.Payload.(*extensions.IqVcardTemp)
if ok { if ok {
go handleGetVcardIq(s, iq, TypeVCardTemp) go handleGetVcardIq(s, iq, TypeVCardTemp)
@ -68,12 +69,18 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
go handleGetQueryRegister(s, iq) go handleGetQueryRegister(s, iq)
return return
} }
} else if iq.Type == "set" { } else if iq.Type == stanza.IQTypeSet {
query, ok := iq.Payload.(*extensions.QueryRegister) query, ok := iq.Payload.(*extensions.QueryRegister)
if ok { if ok {
go handleSetQueryRegister(s, iq, query) go handleSetQueryRegister(s, iq, query)
return return
} }
} else if iq.Type == stanza.IQTypeResult {
discoInfo, ok := iq.Payload.(*stanza.DiscoInfo)
if ok {
go handleClientFeatures(iq, discoInfo)
return
}
} }
} }
@ -412,6 +419,7 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
newArgs..., newArgs...,
) )
} }
probeClientFeatures(p.From, component)
session.UpdateChatNicknames() session.UpdateChatNicknames()
} }
}() }()
@ -687,6 +695,53 @@ func iqAnswerSetError(answer *stanza.IQ, payload *extensions.QueryRegister, code
} }
} }
func probeClientFeatures(jid string, component *xmpp.Component) {
id, err := uuid.NewRandom()
if err != nil {
log.Error("Could not generate ID for a client features probe")
return
}
probe := stanza.IQ{
Attrs: stanza.Attrs{
From: gateway.Jid.Bare(),
To: jid,
Id: id.String(),
Type: stanza.IQTypeGet,
},
Payload: &stanza.DiscoInfo{},
}
log.Debugf("%#v", probe)
gateway.ResumableSend(component, &probe)
}
func handleClientFeatures(iq *stanza.IQ, discoInfo *stanza.DiscoInfo) {
fromJid, err := stanza.NewJid(iq.From)
if err != nil {
log.Error("Invalid from JID!")
return
}
bareFrom := fromJid.Bare()
session, ok := sessions[bareFrom]
if !ok {
log.Errorf("Got client features for unknown JID %v", bareFrom)
return
}
var features []string
for _, feature := range discoInfo.Features {
features = append(features, feature.Var)
}
session.XmppClientFeaturesLock.Lock()
session.XmppClientFeatures[fromJid.Resource] = &features
session.XmppClientFeaturesLock.Unlock()
log.Debugf("Features for %v: %#v", iq.From, features)
}
func toToID(to string) (int64, bool) { func toToID(to string) (int64, bool) {
toParts := strings.Split(to, "@") toParts := strings.Split(to, "@")
if len(toParts) < 2 { if len(toParts) < 2 {