diff --git a/src/api/api.go b/src/api/api.go index c4c0731..4b3bdbb 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -2408,6 +2408,7 @@ func (a *Api) AddStickerPack(c *gin.Context) { // @Produce json // @Success 200 {object} []client.ListContactsResponse // @Param number path string true "Registered Phone Number" +// @Param all_recipients query string false "Include all known recipients, not only contacts." (default: false)" // @Router /v1/contacts/{number} [get] func (a *Api) ListContacts(c *gin.Context) { number, err := url.PathUnescape(c.Param("number")) @@ -2421,8 +2422,12 @@ func (a *Api) ListContacts(c *gin.Context) { return } - contacts, err := a.signalClient.ListContacts(number) - + allRecipients := c.DefaultQuery("all_recipients", "false") + if allRecipients != "true" && allRecipients != "false" { + c.JSON(400, Error{Msg: "Couldn't process request - all_recipients parameter needs to be either 'true' or 'false'"}) + return + } + contacts, err := a.signalClient.ListContacts(number, StringToBool(allRecipients), "") if err != nil { c.JSON(400, Error{Msg: err.Error()}) return @@ -2437,6 +2442,7 @@ func (a *Api) ListContacts(c *gin.Context) { // @Produce json // @Success 200 {object} client.ListContactsResponse // @Param number path string true "Registered Phone Number" +// @Param all_recipients query string false "Include all known recipients, not only contacts." (default: false)" // @Router /v1/contacts/{number}/{uuid} [get] func (a *Api) ListContact(c *gin.Context) { number, err := url.PathUnescape(c.Param("number")) @@ -2456,7 +2462,13 @@ func (a *Api) ListContact(c *gin.Context) { return } - contact, err := a.signalClient.ListContact(number, uuid) + allRecipients := c.DefaultQuery("all_recipients", "false") + if allRecipients != "true" && allRecipients != "false" { + c.JSON(400, Error{Msg: "Couldn't process request - all_recipients parameter needs to be either 'true' or 'false'"}) + return + } + + contacts, err := a.signalClient.ListContacts(number, StringToBool(allRecipients), uuid) if err != nil { switch err.(type) { case *client.NotFoundError: @@ -2468,7 +2480,7 @@ func (a *Api) ListContact(c *gin.Context) { } } - c.JSON(200, contact) + c.JSON(200, contacts[0]) } // @Summary Returns the avatar of a contact diff --git a/src/client/client.go b/src/client/client.go index 9ec41f8..d6c41ed 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -2602,7 +2602,7 @@ func (s *SignalClient) AddStickerPack(number string, packId string, packKey stri } } -func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, error) { +func (s *SignalClient) ListContacts(number string, allRecipients bool, recipient string) ([]ListContactsResponse, error) { type SignalCliProfileResponse struct { LastUpdateTimestamp int64 `json:"lastUpdateTimestamp"` GivenName string `json:"givenName"` @@ -2611,7 +2611,7 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro HasAvatar bool `json:"hasAvatar"` } - type ListContactsSignlCliResponse struct { + type ListContactsSignalCliResponse struct { Number string `json:"number"` Uuid string `json:"uuid"` Name string `json:"name"` @@ -2634,29 +2634,51 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro var rawData string if s.signalCliMode == JsonRpc { + type Request struct { + AllRecipients bool `json:"allRecipients,omitempty"` + Recipient string `json:"recipient,omitempty"` + } + req := Request{} + if allRecipients { + req.AllRecipients = allRecipients + } + if recipient != "" { + req.Recipient = recipient + } + jsonRpc2Client, err := s.getJsonRpc2Client() if err != nil { return nil, err } - rawData, err = jsonRpc2Client.getRaw("listContacts", &number, nil) + rawData, err = jsonRpc2Client.getRaw("listContacts", &number, req) if err != nil { return resp, err } } else { cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "listContacts"} + if allRecipients { + cmd = append(cmd, "--all-recipients") + } + if recipient != "" { + cmd = append(cmd, recipient) + } rawData, err = s.cliClient.Execute(true, cmd, "") if err != nil { return resp, err } } - var signalCliResp []ListContactsSignlCliResponse + var signalCliResp []ListContactsSignalCliResponse err = json.Unmarshal([]byte(rawData), &signalCliResp) if err != nil { log.Error("Couldn't list contacts", err.Error()) return resp, errors.New("Couldn't process request - invalid signal-cli response") } + if recipient != "" && len(signalCliResp) == 0 { + return resp, &NotFoundError{Description: "No user with that id (" + recipient + ") found"} + } + for _, value := range signalCliResp { entry := ListContactsResponse{ Number: value.Number, @@ -2684,20 +2706,6 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro return resp, nil } -func (s *SignalClient) ListContact(number string, uuid string) (ListContactsResponse, error) { - contacts, err := s.ListContacts(number) - if err != nil { - return ListContactsResponse{}, err - } - - for _, contact := range contacts { - if contact.Uuid == uuid { - return contact, nil - } - } - - return ListContactsResponse{}, &NotFoundError{Description: "No contact with that id (" + uuid + ") found"} -} func (s *SignalClient) SetPin(number string, registrationLockPin string) error { if s.signalCliMode == JsonRpc { diff --git a/src/docs/docs.go b/src/docs/docs.go index f4fdbf7..3bf19e9 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -573,6 +573,12 @@ const docTemplate = `{ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -682,6 +688,12 @@ const docTemplate = `{ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -2653,7 +2665,7 @@ const docTemplate = `{ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -2727,32 +2739,6 @@ const docTemplate = `{ } } }, - "api.GroupPermissions": { - "type": "object", - "properties": { - "add_members": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "edit_group": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "send_messages": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - } - } - }, "api.LoggingConfiguration": { "type": "object", "properties": { @@ -3085,7 +3071,7 @@ const docTemplate = `{ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3230,6 +3216,9 @@ const docTemplate = `{ "items": { "type": "string" } + }, + "permissions": { + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3359,6 +3348,32 @@ const docTemplate = `{ } } }, + "data.GroupPermissions": { + "type": "object", + "properties": { + "add_members": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "edit_group": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "send_messages": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + } + } + }, "data.LinkPreviewType": { "type": "object", "properties": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index e509ae1..8e10645 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -570,6 +570,12 @@ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -679,6 +685,12 @@ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -2650,7 +2662,7 @@ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -2724,32 +2736,6 @@ } } }, - "api.GroupPermissions": { - "type": "object", - "properties": { - "add_members": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "edit_group": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "send_messages": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - } - } - }, "api.LoggingConfiguration": { "type": "object", "properties": { @@ -3082,7 +3068,7 @@ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3227,6 +3213,9 @@ "items": { "type": "string" } + }, + "permissions": { + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3356,6 +3345,32 @@ } } }, + "data.GroupPermissions": { + "type": "object", + "properties": { + "add_members": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "edit_group": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "send_messages": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + } + } + }, "data.LinkPreviewType": { "type": "object", "properties": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 7e7ee54..48c00b5 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -61,7 +61,7 @@ definitions: name: type: string permissions: - $ref: '#/definitions/api.GroupPermissions' + $ref: '#/definitions/data.GroupPermissions' type: object api.CreateGroupResponse: properties: @@ -110,24 +110,6 @@ definitions: error: type: string type: object - api.GroupPermissions: - properties: - add_members: - enum: - - only-admins - - every-member - type: string - edit_group: - enum: - - only-admins - - every-member - type: string - send_messages: - enum: - - only-admins - - every-member - type: string - type: object api.LoggingConfiguration: properties: Level: @@ -349,7 +331,7 @@ definitions: name: type: string permissions: - $ref: '#/definitions/api.GroupPermissions' + $ref: '#/definitions/data.GroupPermissions' type: object api.UpdateProfileRequest: properties: @@ -445,6 +427,8 @@ definitions: items: type: string type: array + permissions: + $ref: '#/definitions/data.GroupPermissions' type: object client.IdentityEntry: properties: @@ -528,6 +512,24 @@ definitions: username_link: type: string type: object + data.GroupPermissions: + properties: + add_members: + enum: + - only-admins + - every-member + type: string + edit_group: + enum: + - only-admins + - every-member + type: string + send_messages: + enum: + - only-admins + - every-member + type: string + type: object data.LinkPreviewType: properties: base64_thumbnail: @@ -928,6 +930,10 @@ paths: name: number required: true type: string + - description: Include all known recipients, not only contacts. + in: query + name: all_recipients + type: string produces: - application/json responses: @@ -978,6 +984,10 @@ paths: name: number required: true type: string + - description: Include all known recipients, not only contacts. + in: query + name: all_recipients + type: string produces: - application/json responses: