From a21cbec9ec09a78a1b339df61a37fe39a67dcd23 Mon Sep 17 00:00:00 2001
From: Bohdan Horbeshko <bodqhrohro@gmail.com>
Date: Sun, 12 May 2024 09:13:13 -0400
Subject: [PATCH] Support multiple command elements

---
 stanza/commands.go     | 10 +++++-----
 stanza/pubsub_owner.go | 21 ++++++++++++++-------
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/stanza/commands.go b/stanza/commands.go
index 0009a02..5ce8b14 100644
--- a/stanza/commands.go
+++ b/stanza/commands.go
@@ -23,7 +23,7 @@ const (
 type Command struct {
 	XMLName xml.Name `xml:"http://jabber.org/protocol/commands command"`
 
-	CommandElement CommandElement
+	CommandElements []CommandElement
 
 	BadAction       *struct{} `xml:"bad-action,omitempty"`
 	BadLocale       *struct{} `xml:"bad-locale,omitempty"`
@@ -124,19 +124,19 @@ func (c *Command) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
 			case "actions":
 				a := Actions{}
 				err = d.DecodeElement(&a, &tt)
-				c.CommandElement = &a
+				c.CommandElements = append(c.CommandElements, &a)
 			case "note":
 				nt := Note{}
 				err = d.DecodeElement(&nt, &tt)
-				c.CommandElement = &nt
+				c.CommandElements = append(c.CommandElements, &nt)
 			case "x":
 				f := Form{}
 				err = d.DecodeElement(&f, &tt)
-				c.CommandElement = &f
+				c.CommandElements = append(c.CommandElements, &f)
 			default:
 				n := Node{}
 				err = d.DecodeElement(&n, &tt)
-				c.CommandElement = &n
+				c.CommandElements = append(c.CommandElements, &n)
 				if err != nil {
 					return err
 				}
diff --git a/stanza/pubsub_owner.go b/stanza/pubsub_owner.go
index 32d2773..d4c9843 100644
--- a/stanza/pubsub_owner.go
+++ b/stanza/pubsub_owner.go
@@ -237,10 +237,10 @@ func NewApprovePendingSubRequest(serviceId, sessionId, nodeId string) (*IQ, erro
 	}
 	iq.Payload = &Command{
 		//  the command name ('node' attribute of the command element) MUST have a value of "http://jabber.org/protocol/pubsub#get-pending"
-		Node:           "http://jabber.org/protocol/pubsub#get-pending",
-		Action:         CommandActionExecute,
-		SessionId:      sessionId,
-		CommandElement: &n,
+		Node:            "http://jabber.org/protocol/pubsub#get-pending",
+		Action:          CommandActionExecute,
+		SessionId:       sessionId,
+		CommandElements: []CommandElement{&n},
 	}
 	return iq, nil
 }
@@ -353,11 +353,18 @@ func (iq *IQ) GetFormFields() (map[string]*Field, error) {
 
 	case *Command:
 		fieldMap := make(map[string]*Field)
-		co, ok := payload.CommandElement.(*Form)
-		if !ok {
+		var form *Form
+		for _, ce := range payload.CommandElements {
+			fo, ok := ce.(*Form)
+			if ok {
+				form = fo
+				break
+			}
+		}
+		if form == nil {
 			return nil, errors.New("this IQ does not contain a command payload with a form")
 		}
-		for _, elt := range co.Fields {
+		for _, elt := range form.Fields {
 			fieldMap[elt.Var] = elt
 		}
 		return fieldMap, nil