diff --git a/src/api/api.go b/src/api/api.go index 0bbdecd..73a7bb9 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "net/http" + "net/url" "strconv" "strings" "sync" @@ -232,7 +233,10 @@ func (a *Api) About(c *gin.Context) { // @Param data body RegisterNumberRequest false "Additional Settings" // @Router /v1/register/{number} [post] func (a *Api) RegisterNumber(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } var req RegisterNumberRequest @@ -255,7 +259,7 @@ func (a *Api) RegisterNumber(c *gin.Context) { return } - err := a.signalClient.RegisterNumber(number, req.UseVoice, req.Captcha) + err = a.signalClient.RegisterNumber(number, req.UseVoice, req.Captcha) if err != nil { c.JSON(400, gin.H{"error": err.Error()}) return @@ -274,7 +278,10 @@ func (a *Api) RegisterNumber(c *gin.Context) { // @Param data body UnregisterNumberRequest false "Additional Settings" // @Router /v1/unregister/{number} [post] func (a *Api) UnregisterNumber(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } deleteAccount := false deleteLocalData := false @@ -292,7 +299,7 @@ func (a *Api) UnregisterNumber(c *gin.Context) { deleteLocalData = req.DeleteLocalData } - err := a.signalClient.UnregisterNumber(number, deleteAccount, deleteLocalData) + err = a.signalClient.UnregisterNumber(number, deleteAccount, deleteLocalData) if err != nil { c.JSON(400, gin.H{"error": err.Error()}) return @@ -312,7 +319,10 @@ func (a *Api) UnregisterNumber(c *gin.Context) { // @Param token path string true "Verification Code" // @Router /v1/register/{number}/verify/{token} [post] func (a *Api) VerifyRegisteredNumber(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } token := c.Param("token") pin := "" @@ -339,7 +349,7 @@ func (a *Api) VerifyRegisteredNumber(c *gin.Context) { return } - err := a.signalClient.VerifyRegisteredNumber(number, token, pin) + err = a.signalClient.VerifyRegisteredNumber(number, token, pin) if err != nil { c.JSON(400, gin.H{"error": err.Error()}) return @@ -566,7 +576,10 @@ func StringToBool(input string) bool { // @Param send_read_receipts query string false "Specify whether read receipts should be sent when receiving messages" (default: false)" // @Router /v1/receive/{number} [get] func (a *Api) Receive(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if a.signalClient.GetSignalCliMode() == client.JsonRpc { ws, err := connectionUpgrader.Upgrade(c.Writer, c.Request, nil) @@ -633,10 +646,13 @@ func (a *Api) Receive(c *gin.Context) { // @Param number path string true "Registered Phone Number" // @Router /v1/groups/{number} [post] func (a *Api) CreateGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } var req CreateGroupRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -691,7 +707,10 @@ func (a *Api) CreateGroup(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid}/members [post] func (a *Api) AddMembersToGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -704,7 +723,7 @@ func (a *Api) AddMembersToGroup(c *gin.Context) { } var req ChangeGroupMembersRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -736,7 +755,10 @@ func (a *Api) AddMembersToGroup(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid}/members [delete] func (a *Api) RemoveMembersFromGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -749,7 +771,7 @@ func (a *Api) RemoveMembersFromGroup(c *gin.Context) { } var req ChangeGroupMembersRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -781,7 +803,10 @@ func (a *Api) RemoveMembersFromGroup(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid}/admins [post] func (a *Api) AddAdminsToGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -794,7 +819,7 @@ func (a *Api) AddAdminsToGroup(c *gin.Context) { } var req ChangeGroupAdminsRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -826,7 +851,10 @@ func (a *Api) AddAdminsToGroup(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid}/admins [delete] func (a *Api) RemoveAdminsFromGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -839,7 +867,7 @@ func (a *Api) RemoveAdminsFromGroup(c *gin.Context) { } var req ChangeGroupAdminsRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -869,8 +897,10 @@ func (a *Api) RemoveAdminsFromGroup(c *gin.Context) { // @Param number path string true "Registered Phone Number" // @Router /v1/groups/{number} [get] func (a *Api) GetGroups(c *gin.Context) { - raw := c.Param("number") - number := strings.Replace(raw, "%2B", "+", 1) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } groups, err := a.signalClient.GetGroups(number) if err != nil { @@ -892,7 +922,10 @@ func (a *Api) GetGroups(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid} [get] func (a *Api) GetGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } groupId := c.Param("groupid") groupEntry, err := a.signalClient.GetGroup(number, groupId) @@ -920,7 +953,10 @@ func (a *Api) GetGroup(c *gin.Context) { // @Router /v1/groups/{number}/{groupid} [delete] func (a *Api) DeleteGroup(c *gin.Context) { base64EncodedGroupId := c.Param("groupid") - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if base64EncodedGroupId == "" { c.JSON(400, Error{Msg: "Please specify a group id"}) @@ -1097,7 +1133,10 @@ func (a *Api) ServeAttachment(c *gin.Context) { // @Param number path string true "Registered Phone Number" // @Router /v1/profiles/{number} [put] func (a *Api) UpdateProfile(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) @@ -1105,7 +1144,7 @@ func (a *Api) UpdateProfile(c *gin.Context) { } var req UpdateProfileRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) log.Error(err.Error()) @@ -1144,7 +1183,10 @@ func (a *Api) Health(c *gin.Context) { // @Param number path string true "Registered Phone Number" // @Router /v1/identities/{number} [get] func (a *Api) ListIdentities(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) @@ -1170,7 +1212,10 @@ func (a *Api) ListIdentities(c *gin.Context) { // @Param numberToTrust path string true "Number To Trust" // @Router /v1/identities/{number}/trust/{numberToTrust} [put] func (a *Api) TrustIdentity(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) @@ -1184,7 +1229,7 @@ func (a *Api) TrustIdentity(c *gin.Context) { } var req TrustIdentityRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) log.Error(err.Error()) @@ -1281,7 +1326,10 @@ func (a *Api) GetConfiguration(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid}/block [post] func (a *Api) BlockGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -1314,7 +1362,10 @@ func (a *Api) BlockGroup(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid}/join [post] func (a *Api) JoinGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -1347,7 +1398,10 @@ func (a *Api) JoinGroup(c *gin.Context) { // @Param groupid path string true "Group ID" // @Router /v1/groups/{number}/{groupid}/quit [post] func (a *Api) QuitGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -1380,7 +1434,10 @@ func (a *Api) QuitGroup(c *gin.Context) { // @Param data body UpdateGroupRequest true "Input Data" // @Router /v1/groups/{number}/{groupid} [put] func (a *Api) UpdateGroup(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -1427,7 +1484,10 @@ func (a *Api) SendReaction(c *gin.Context) { return } - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if req.Recipient == "" { c.JSON(400, Error{Msg: "Couldn't process request - recipient missing"}) @@ -1475,7 +1535,10 @@ func (a *Api) RemoveReaction(c *gin.Context) { return } - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if req.Recipient == "" { c.JSON(400, Error{Msg: "Couldn't process request - recipient missing"}) @@ -1518,7 +1581,10 @@ func (a *Api) SendReceipt(c *gin.Context) { return } - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) @@ -1568,7 +1634,10 @@ func (a *Api) SendStartTyping(c *gin.Context) { return } - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -1601,7 +1670,10 @@ func (a *Api) SendStopTyping(c *gin.Context) { return } - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -1632,7 +1704,10 @@ func (a *Api) SearchForNumbers(c *gin.Context) { return } - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } searchResults, err := a.signalClient.SearchForNumbers(number, query["numbers"]) if err != nil { @@ -1660,14 +1735,17 @@ func (a *Api) SearchForNumbers(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/contacts/{number} [put] func (a *Api) UpdateContact(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } var req UpdateContactRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -1697,14 +1775,17 @@ func (a *Api) UpdateContact(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/devices/{number} [post] func (a *Api) AddDevice(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } var req AddDeviceRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -1729,14 +1810,17 @@ func (a *Api) AddDevice(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/configuration/{number}/settings [post] func (a *Api) SetTrustMode(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } var req TrustModeRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -1768,13 +1852,15 @@ func (a *Api) SetTrustMode(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/configuration/{number}/settings [get] func (a *Api) GetTrustMode(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } - var err error trustMode := TrustModeResponse{} trustMode.TrustMode, err = utils.TrustModeToString(a.signalClient.GetTrustMode(number)) if err != nil { @@ -1796,13 +1882,16 @@ func (a *Api) GetTrustMode(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/contacts/{number}/sync [post] func (a *Api) SendContacts(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } - err := a.signalClient.SendContacts(number) + err = a.signalClient.SendContacts(number) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return @@ -1821,14 +1910,17 @@ func (a *Api) SendContacts(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/accounts/{number}/rate-limit-challenge [post] func (a *Api) SubmitRateLimitChallenge(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } var req RateLimitChallengeRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -1853,14 +1945,17 @@ func (a *Api) SubmitRateLimitChallenge(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/accounts/{number}/settings [put] func (a *Api) UpdateAccountSettings(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } var req UpdateAccountSettingsRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -1887,14 +1982,17 @@ func (a *Api) UpdateAccountSettings(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/accounts/{number}/username [post] func (a *Api) SetUsername(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } var req SetUsernameRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -1918,13 +2016,16 @@ func (a *Api) SetUsername(c *gin.Context) { // @Failure 400 {object} Error // @Router /v1/accounts/{number}/username [delete] func (a *Api) RemoveUsername(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } - err := a.signalClient.RemoveUsername(number) + err = a.signalClient.RemoveUsername(number) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return @@ -1943,7 +2044,10 @@ func (a *Api) RemoveUsername(c *gin.Context) { // @Success 200 {object} []client.ListInstalledStickerPacksResponse // @Router /v1/sticker-packs/{number} [get] func (a *Api) ListInstalledStickerPacks(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return @@ -1969,14 +2073,17 @@ func (a *Api) ListInstalledStickerPacks(c *gin.Context) { // @Param data body AddStickerPackRequest true "Request" // @Router /v1/sticker-packs/{number} [post] func (a *Api) AddStickerPack(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) return } var req AddStickerPackRequest - err := c.BindJSON(&req) + err = c.BindJSON(&req) if err != nil { c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) return @@ -1999,7 +2106,10 @@ func (a *Api) AddStickerPack(c *gin.Context) { // @Param number path string true "Registered Phone Number" // @Router /v1/contacts/{number} [get] func (a *Api) ListContacts(c *gin.Context) { - number := parseNumber(c) + number, err := url.PathUnescape(c.Param("number")) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - malformed number"}) + } if number == "" { c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) @@ -2015,9 +2125,3 @@ func (a *Api) ListContacts(c *gin.Context) { c.JSON(200, contacts) } - -func parseNumber(c *gin.Context) string { - raw := c.Param("number") - number := strings.Replace(raw, "%2B", "+", 1) - return number -}