Merge branch 'master' of github.com:bbernhard/signal-cli-rest-api

This commit is contained in:
Jailson Dias 2024-11-13 16:40:14 -03:00
commit 14ab19afcd
11 changed files with 524 additions and 72 deletions

View File

@ -1,6 +1,6 @@
ARG SIGNAL_CLI_VERSION=0.13.7
ARG LIBSIGNAL_CLIENT_VERSION=0.58.0
ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION=0.13.7+morph027+1
ARG SIGNAL_CLI_VERSION=0.13.9
ARG LIBSIGNAL_CLIENT_VERSION=0.58.2
ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION=0.13.9+morph027+1
ARG SWAG_VERSION=1.6.7
ARG GRAALVM_VERSION=21.0.0

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"net/http"
"net/url"
"strconv"
"strings"
"sync"
@ -144,8 +145,9 @@ type CreateGroupResponse struct {
}
type UpdateProfileRequest struct {
Name string `json:"name"`
Base64Avatar string `json:"base64_avatar"`
Name string `json:"name"`
Base64Avatar string `json:"base64_avatar"`
About *string `json:"about"`
}
type TrustIdentityRequest struct {
@ -231,7 +233,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
var req RegisterNumberRequest
@ -254,7 +260,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
@ -273,7 +279,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
deleteAccount := false
deleteLocalData := false
@ -291,7 +301,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
@ -311,7 +321,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
token := c.Param("token")
pin := ""
@ -338,7 +352,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
@ -565,7 +579,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if a.signalClient.GetSignalCliMode() == client.JsonRpc {
ws, err := connectionUpgrader.Upgrade(c.Writer, c.Request, nil)
@ -632,10 +650,14 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -690,7 +712,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -703,7 +729,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
@ -735,7 +761,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -748,7 +778,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
@ -780,7 +810,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -793,7 +827,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
@ -825,7 +859,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -838,7 +876,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
@ -868,7 +906,11 @@ 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) {
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
groups, err := a.signalClient.GetGroups(number)
if err != nil {
@ -890,7 +932,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
groupId := c.Param("groupid")
groupEntry, err := a.signalClient.GetGroup(number, groupId)
@ -918,7 +964,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if base64EncodedGroupId == "" {
c.JSON(400, Error{Msg: "Please specify a group id"})
@ -1095,7 +1145,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
@ -1103,7 +1157,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())
@ -1115,7 +1169,7 @@ func (a *Api) UpdateProfile(c *gin.Context) {
return
}
err = a.signalClient.UpdateProfile(number, req.Name, req.Base64Avatar)
err = a.signalClient.UpdateProfile(number, req.Name, req.Base64Avatar, req.About)
if err != nil {
c.JSON(400, Error{Msg: err.Error()})
return
@ -1142,7 +1196,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
@ -1168,7 +1226,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
@ -1182,7 +1244,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())
@ -1279,7 +1341,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -1312,7 +1378,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -1372,7 +1442,11 @@ func (a *Api) JoinGroupByInviteLink(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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -1405,7 +1479,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -1442,6 +1520,7 @@ func (a *Api) UpdateGroup(c *gin.Context) {
// @Success 204 {string} OK
// @Failure 400 {object} Error
// @Param data body Reaction true "Reaction"
// @Param number path string true "Registered phone number"
// @Router /v1/reactions/{number} [post]
func (a *Api) SendReaction(c *gin.Context) {
var req Reaction
@ -1452,7 +1531,11 @@ func (a *Api) SendReaction(c *gin.Context) {
return
}
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if req.Recipient == "" {
c.JSON(400, Error{Msg: "Couldn't process request - recipient missing"})
@ -1490,6 +1573,7 @@ func (a *Api) SendReaction(c *gin.Context) {
// @Success 204 {string} OK
// @Failure 400 {object} Error
// @Param data body Reaction true "Reaction"
// @Param number path string true "Registered phone number"
// @Router /v1/reactions/{number} [delete]
func (a *Api) RemoveReaction(c *gin.Context) {
var req Reaction
@ -1500,7 +1584,11 @@ func (a *Api) RemoveReaction(c *gin.Context) {
return
}
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if req.Recipient == "" {
c.JSON(400, Error{Msg: "Couldn't process request - recipient missing"})
@ -1533,6 +1621,7 @@ func (a *Api) RemoveReaction(c *gin.Context) {
// @Success 204 {string} OK
// @Failure 400 {object} Error
// @Param data body Receipt true "Receipt"
// @Param number path string true "Registered phone number"
// @Router /v1/receipts/{number} [post]
func (a *Api) SendReceipt(c *gin.Context) {
var req Receipt
@ -1543,7 +1632,11 @@ func (a *Api) SendReceipt(c *gin.Context) {
return
}
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
@ -1593,7 +1686,11 @@ func (a *Api) SendStartTyping(c *gin.Context) {
return
}
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -1626,7 +1723,11 @@ func (a *Api) SendStopTyping(c *gin.Context) {
return
}
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -1657,7 +1758,11 @@ func (a *Api) SearchForNumbers(c *gin.Context) {
return
}
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
searchResults, err := a.signalClient.SearchForNumbers(number, query["numbers"])
if err != nil {
@ -1685,14 +1790,18 @@ func (a *Api) SearchForNumbers(c *gin.Context) {
// @Failure 400 {object} Error
// @Router /v1/contacts/{number} [put]
func (a *Api) UpdateContact(c *gin.Context) {
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1722,14 +1831,18 @@ func (a *Api) UpdateContact(c *gin.Context) {
// @Failure 400 {object} Error
// @Router /v1/devices/{number} [post]
func (a *Api) AddDevice(c *gin.Context) {
number := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1754,14 +1867,18 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1793,13 +1910,16 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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 {
@ -1821,13 +1941,17 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1846,14 +1970,18 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1878,14 +2006,18 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1912,14 +2044,18 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1943,13 +2079,17 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -1968,7 +2108,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
@ -1994,14 +2138,18 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
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
@ -2024,7 +2172,11 @@ 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 := c.Param("number")
number, err := url.PathUnescape(c.Param("number"))
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - malformed number"})
return
}
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})

View File

@ -462,7 +462,10 @@ func (s *SignalClient) send(signalCliSendRequest ds.SignalCliSendRequest) (*Send
request.Attachments = append(request.Attachments, attachmentEntry.toDataForSignal())
}
request.NotifySelf = true
// for backwards compatibility, if flag is not set we'll assume that self notification is desired
if signalCliSendRequest.NotifySelf == nil || *signalCliSendRequest.NotifySelf {
request.NotifySelf = true
}
request.Sticker = signalCliSendRequest.Sticker
if signalCliSendRequest.Mentions != nil {
@ -1357,7 +1360,7 @@ func (s *SignalClient) GetAttachment(attachment string) ([]byte, error) {
return attachmentBytes, nil
}
func (s *SignalClient) UpdateProfile(number string, profileName string, base64Avatar string) error {
func (s *SignalClient) UpdateProfile(number string, profileName string, base64Avatar string, about *string) error {
var err error
var avatarTmpPath string
if base64Avatar != "" {
@ -1397,17 +1400,20 @@ func (s *SignalClient) UpdateProfile(number string, profileName string, base64Av
if s.signalCliMode == JsonRpc {
type Request struct {
Name string `json:"given-name"`
Avatar string `json:"avatar,omitempty"`
RemoveAvatar bool `json:"remove-avatar"`
Name string `json:"given-name"`
Avatar string `json:"avatar,omitempty"`
RemoveAvatar bool `json:"remove-avatar"`
About *string `json:"about,omitempty"`
}
request := Request{Name: profileName}
request.About = about
if base64Avatar == "" {
request.RemoveAvatar = true
} else {
request.Avatar = avatarTmpPath
request.RemoveAvatar = false
}
jsonRpc2Client, err := s.getJsonRpc2Client()
if err != nil {
return err
@ -1421,6 +1427,10 @@ func (s *SignalClient) UpdateProfile(number string, profileName string, base64Av
cmd = append(cmd, []string{"--avatar", avatarTmpPath}...)
}
if about != nil {
cmd = append(cmd, []string{"--about", *about}...)
}
_, err = s.cliClient.Execute(true, cmd, "")
}

13
src/docs/README.md Normal file
View File

@ -0,0 +1,13 @@
These files are generated from the [swaggo/swag](https://github.com/swaggo/swag) tool.
To regenerate them, run in /src:
```bash
docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest init
```
Or, if you have `swag` installed:
```bash
swag init
```

View File

@ -1415,6 +1415,13 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/api.Reaction"
}
},
{
"type": "string",
"description": "Registered phone number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
@ -1453,6 +1460,13 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/api.Reaction"
}
},
{
"type": "string",
"description": "Registered phone number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
@ -1493,6 +1507,13 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/api.Receipt"
}
},
{
"type": "string",
"description": "Registered phone number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
@ -2278,7 +2299,69 @@ const docTemplate = `{
}
},
"api.SendMessageV2": {
"type": "object"
"type": "object",
"properties": {
"base64_attachments": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"\u003cBASE64 ENCODED DATA\u003e",
"data:\u003cMIME-TYPE\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e",
"data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e"
]
},
"edit_timestamp": {
"type": "integer"
},
"mentions": {
"type": "array",
"items": {
"$ref": "#/definitions/data.MessageMention"
}
},
"message": {
"type": "string"
},
"notify_self": {
"type": "boolean"
},
"number": {
"type": "string"
},
"quote_author": {
"type": "string"
},
"quote_mentions": {
"type": "array",
"items": {
"$ref": "#/definitions/data.MessageMention"
}
},
"quote_message": {
"type": "string"
},
"quote_timestamp": {
"type": "integer"
},
"recipients": {
"type": "array",
"items": {
"type": "string"
}
},
"sticker": {
"type": "string"
},
"text_mode": {
"type": "string",
"enum": [
"normal",
"styled"
]
}
}
},
"api.SetUsernameRequest": {
"type": "object",
@ -2380,6 +2463,9 @@ const docTemplate = `{
"api.UpdateProfileRequest": {
"type": "object",
"properties": {
"about": {
"type": "string"
},
"base64_avatar": {
"type": "string"
},
@ -2548,6 +2634,20 @@ const docTemplate = `{
"type": "string"
}
}
},
"data.MessageMention": {
"type": "object",
"properties": {
"author": {
"type": "string"
},
"length": {
"type": "integer"
},
"start": {
"type": "integer"
}
}
}
},
"tags": [
@ -2605,9 +2705,9 @@ const docTemplate = `{
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0",
Host: "",
Host: "localhost:8080",
BasePath: "/",
Schemes: []string{},
Schemes: []string{"http"},
Title: "Signal Cli REST API",
Description: "This is the Signal Cli REST API documentation.",
InfoInstanceName: "swagger",

View File

@ -1,4 +1,7 @@
{
"schemes": [
"http"
],
"swagger": "2.0",
"info": {
"description": "This is the Signal Cli REST API documentation.",
@ -6,6 +9,7 @@
"contact": {},
"version": "1.0"
},
"host": "localhost:8080",
"basePath": "/",
"paths": {
"/v1/about": {
@ -1408,6 +1412,13 @@
"schema": {
"$ref": "#/definitions/api.Reaction"
}
},
{
"type": "string",
"description": "Registered phone number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
@ -1446,6 +1457,13 @@
"schema": {
"$ref": "#/definitions/api.Reaction"
}
},
{
"type": "string",
"description": "Registered phone number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
@ -1486,6 +1504,13 @@
"schema": {
"$ref": "#/definitions/api.Receipt"
}
},
{
"type": "string",
"description": "Registered phone number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
@ -2271,7 +2296,69 @@
}
},
"api.SendMessageV2": {
"type": "object"
"type": "object",
"properties": {
"base64_attachments": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"\u003cBASE64 ENCODED DATA\u003e",
"data:\u003cMIME-TYPE\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e",
"data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e"
]
},
"edit_timestamp": {
"type": "integer"
},
"mentions": {
"type": "array",
"items": {
"$ref": "#/definitions/data.MessageMention"
}
},
"message": {
"type": "string"
},
"notify_self": {
"type": "boolean"
},
"number": {
"type": "string"
},
"quote_author": {
"type": "string"
},
"quote_mentions": {
"type": "array",
"items": {
"$ref": "#/definitions/data.MessageMention"
}
},
"quote_message": {
"type": "string"
},
"quote_timestamp": {
"type": "integer"
},
"recipients": {
"type": "array",
"items": {
"type": "string"
}
},
"sticker": {
"type": "string"
},
"text_mode": {
"type": "string",
"enum": [
"normal",
"styled"
]
}
}
},
"api.SetUsernameRequest": {
"type": "object",
@ -2373,6 +2460,9 @@
"api.UpdateProfileRequest": {
"type": "object",
"properties": {
"about": {
"type": "string"
},
"base64_avatar": {
"type": "string"
},
@ -2541,6 +2631,20 @@
"type": "string"
}
}
},
"data.MessageMention": {
"type": "object",
"properties": {
"author": {
"type": "string"
},
"length": {
"type": "integer"
},
"start": {
"type": "integer"
}
}
}
},
"tags": [

View File

@ -163,6 +163,48 @@ definitions:
type: array
type: object
api.SendMessageV2:
properties:
base64_attachments:
example:
- <BASE64 ENCODED DATA>
- data:<MIME-TYPE>;base64<comma><BASE64 ENCODED DATA>
- data:<MIME-TYPE>;filename=<FILENAME>;base64<comma><BASE64 ENCODED DATA>
items:
type: string
type: array
edit_timestamp:
type: integer
mentions:
items:
$ref: '#/definitions/data.MessageMention'
type: array
message:
type: string
notify_self:
type: boolean
number:
type: string
quote_author:
type: string
quote_mentions:
items:
$ref: '#/definitions/data.MessageMention'
type: array
quote_message:
type: string
quote_timestamp:
type: integer
recipients:
items:
type: string
type: array
sticker:
type: string
text_mode:
enum:
- normal
- styled
type: string
type: object
api.SetUsernameRequest:
properties:
@ -229,6 +271,8 @@ definitions:
type: object
api.UpdateProfileRequest:
properties:
about:
type: string
base64_avatar:
type: string
name:
@ -339,6 +383,16 @@ definitions:
username_link:
type: string
type: object
data.MessageMention:
properties:
author:
type: string
length:
type: integer
start:
type: integer
type: object
host: localhost:8080
info:
contact: {}
description: This is the Signal Cli REST API documentation.
@ -1284,6 +1338,11 @@ paths:
required: true
schema:
$ref: '#/definitions/api.Reaction'
- description: Registered phone number
in: path
name: number
required: true
type: string
produces:
- application/json
responses:
@ -1309,6 +1368,11 @@ paths:
required: true
schema:
$ref: '#/definitions/api.Reaction'
- description: Registered phone number
in: path
name: number
required: true
type: string
produces:
- application/json
responses:
@ -1335,6 +1399,11 @@ paths:
required: true
schema:
$ref: '#/definitions/api.Receipt'
- description: Registered phone number
in: path
name: number
required: true
type: string
produces:
- application/json
responses:
@ -1705,6 +1774,8 @@ paths:
summary: Send a signal message.
tags:
- Messages
schemes:
- http
swagger: "2.0"
tags:
- description: Some general endpoints.

View File

@ -59,6 +59,8 @@ import (
// @tag.name Sticker Packs
// @tag.description List and Install Sticker Packs
// @host localhost:8080
// @schemes http
// @BasePath /
func main() {
signalCliConfig := flag.String("signal-cli-config", "/home/.local/share/signal-cli/", "Config directory where signal-cli config is stored")