diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index 435c7d45d..d723ba750 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -318,15 +318,21 @@ func Setup( return CreateRoomCryptoIDs(req, device, cfg, userAPI, rsAPI, asAPI) }), ).Methods(http.MethodPost, http.MethodOptions) - unstableMux.Handle("/org.matrix.msc_cryptoids/sendPDUs", + unstableMux.Handle("/org.matrix.msc_cryptoids/send_pdus/{txnID}", httputil.MakeAuthAPI("send_pdus", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { logrus.Info("Processing request to /org.matrix.msc_cryptoids/sendPDUs") if r := rateLimits.Limit(req, device); r != nil { return *r } + vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) + if err != nil { + return util.ErrorResponse(err) + } + txnID := vars["txnID"] + // NOTE: when making events such as for create_room, multiple PDUs will need to be passed between the client & server. - return SendPDUs(req, device, cfg, userAPI, rsAPI, asAPI) + return SendPDUs(req, device, cfg, userAPI, rsAPI, asAPI, &txnID) }), ).Methods(http.MethodPost, http.MethodOptions) diff --git a/clientapi/routing/send_pdus.go b/clientapi/routing/send_pdus.go index 1959a1fa2..4f7a5e3ba 100644 --- a/clientapi/routing/send_pdus.go +++ b/clientapi/routing/send_pdus.go @@ -32,11 +32,14 @@ import ( "github.com/prometheus/client_golang/prometheus" ) +type PDUInfo struct { + Version string `json:"room_version"` + ViaServer string `json:"via_server,omitempty"` + PDU json.RawMessage `json:"pdu"` +} + type sendPDUsRequest struct { - Version string `json:"room_version"` - ViaServer string `json:"via_server,omitempty"` - TxnID string `json:"txn_id,omitempty"` - PDUs []json.RawMessage `json:"pdus"` + PDUs []PDUInfo `json:"pdus"` } // SendPDUs implements /sendPDUs @@ -45,6 +48,7 @@ func SendPDUs( cfg *config.ClientAPI, profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI, asAPI appserviceAPI.AppServiceInternalAPI, + txnID *string, ) util.JSONResponse { // TODO: cryptoIDs - should this include an "eventType"? // if it's a bulk send endpoint, I don't think that makes any sense since there are multiple event types @@ -79,16 +83,10 @@ func SendPDUs( mutex.(*sync.Mutex).Lock() defer mutex.(*sync.Mutex).Unlock() - var txnID *roomserverAPI.TransactionID - if pdus.TxnID != "" { - txnID.TransactionID = pdus.TxnID - txnID.SessionID = device.SessionID - } - inputs := make([]roomserverAPI.InputRoomEvent, 0, len(pdus.PDUs)) for _, event := range pdus.PDUs { // TODO: cryptoIDs - event hash check? - verImpl, err := gomatrixserverlib.GetRoomVersion(gomatrixserverlib.RoomVersion(pdus.Version)) + verImpl, err := gomatrixserverlib.GetRoomVersion(gomatrixserverlib.RoomVersion(event.Version)) if err != nil { return util.JSONResponse{ Code: http.StatusInternalServerError, @@ -108,7 +106,7 @@ func SendPDUs( // Also - untrusted JSON seems better - except it strips off the unsigned field? // Also - gmsl events don't store the `hashes` field... problem? - pdu, err := verImpl.NewEventFromUntrustedJSON(event) + pdu, err := verImpl.NewEventFromUntrustedJSON(event.PDU) if err != nil { return util.JSONResponse{ Code: http.StatusInternalServerError, @@ -179,7 +177,7 @@ func SendPDUs( RoomID: pdu.RoomID().String(), UserID: device.UserID, IsGuest: device.AccountType == api.AccountTypeGuest, - ServerNames: []spec.ServerName{spec.ServerName(pdus.ViaServer)}, + ServerNames: []spec.ServerName{spec.ServerName(event.ViaServer)}, JoinEvent: pdu, } err := rsAPI.PerformSendJoinCryptoIDs(req.Context(), &joinReq) @@ -200,6 +198,13 @@ func SendPDUs( // We should be doing this already as part of `SendInputRoomEvents`, but how should we pass this // failure back to the client? + var transactionID *roomserverAPI.TransactionID + if txnID != nil { + transactionID = &roomserverAPI.TransactionID{ + SessionID: device.SessionID, TransactionID: *txnID, + } + } + inputs = append(inputs, roomserverAPI.InputRoomEvent{ Kind: roomserverAPI.KindNew, Event: &types.HeaderedEvent{PDU: pdu}, @@ -207,7 +212,7 @@ func SendPDUs( // TODO: cryptoIDs - what to do with this field? // should probably generate this based on the event type being sent? //SendAsServer: roomserverAPI.DoNotSendToOtherServers, - TransactionID: txnID, + TransactionID: transactionID, }) }