added endpoints to set/remove a username + change the account settings

This commit is contained in:
Bernhard B
2024-03-06 18:27:17 +01:00
parent 91d7dc0a19
commit f57512216c
6 changed files with 594 additions and 0 deletions

View File

@@ -168,6 +168,15 @@ type RateLimitChallengeRequest struct {
Captcha string `json:"captcha" example:"signalcaptcha://{captcha value}"`
}
type UpdateAccountSettingsRequest struct {
DiscoverableByNumber *bool `json:"discoverable_by_number"`
ShareNumber *bool `json:"share_number"`
}
type SetUsernameRequest struct {
Username string `json:username" example:"test"`
}
type Api struct {
signalClient *client.SignalClient
}
@@ -1723,3 +1732,93 @@ func (a *Api) SubmitRateLimitChallenge(c *gin.Context) {
}
c.Status(http.StatusNoContent)
}
// @Summary Update the account settings.
// @Tags Accounts
// @Description Update the account attributes on the signal server.
// @Accept json
// @Produce json
// @Param number path string true "Registered Phone Number"
// @Param data body UpdateAccountSettingsRequest true "Request"
// @Success 204
// @Failure 400 {object} Error
// @Router /v1/accounts/{number}/settings [put]
func (a *Api) UpdateAccountSettings(c *gin.Context) {
number := c.Param("number")
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
}
var req UpdateAccountSettingsRequest
err := c.BindJSON(&req)
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - invalid request"})
return
}
err = a.signalClient.UpdateAccountSettings(number, req.DiscoverableByNumber, req.ShareNumber)
if err != nil {
c.JSON(400, Error{Msg: err.Error()})
return
}
c.Status(201)
}
// @Summary Set a username.
// @Tags Accounts
// @Description Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.
// @Accept json
// @Produce json
// @Param number path string true "Registered Phone Number"
// @Param data body SetUsernameRequest true "Request"
// @Success 201 {object} client.SetUsernameResponse
// @Success 204
// @Failure 400 {object} Error
// @Router /v1/accounts/{number}/username [post]
func (a *Api) SetUsername(c *gin.Context) {
number := c.Param("number")
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
}
var req SetUsernameRequest
err := c.BindJSON(&req)
if err != nil {
c.JSON(400, Error{Msg: "Couldn't process request - invalid request"})
return
}
resp, err := a.signalClient.SetUsername(number, req.Username)
if err != nil {
c.JSON(400, Error{Msg: err.Error()})
return
}
c.JSON(201, resp)
}
// @Summary Remove a username.
// @Tags Accounts
// @Description Delete the username associated with this account.
// @Accept json
// @Produce json
// @Param number path string true "Registered Phone Number"
// @Success 204
// @Failure 400 {object} Error
// @Router /v1/accounts/{number}/username [delete]
func (a *Api) RemoveUsername(c *gin.Context) {
number := c.Param("number")
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
}
err := a.signalClient.RemoveUsername(number)
if err != nil {
c.JSON(400, Error{Msg: err.Error()})
return
}
c.Status(http.StatusNoContent)
}

View File

@@ -177,6 +177,11 @@ type SearchResultEntry struct {
Registered bool `json:"registered"`
}
type SetUsernameResponse struct {
Username string `json:"username"`
UsernameLink string `json:"username_link"`
}
func cleanupTmpFiles(paths []string) {
for _, path := range paths {
os.Remove(path)
@@ -1825,3 +1830,88 @@ func (s *SignalClient) SubmitRateLimitChallenge(number string, challengeToken st
return err
}
}
func (s *SignalClient) SetUsername(number string, username string) (SetUsernameResponse, error) {
type SetUsernameSignalCliResponse struct {
Username string `json:"username"`
UsernameLink string `json:"usernameLink"`
}
var resp SetUsernameResponse
var err error
var rawData string
if s.signalCliMode == JsonRpc {
type Request struct {
Username string `json:"username"`
}
request := Request{Username: username}
jsonRpc2Client, err := s.getJsonRpc2Client()
if err != nil {
return resp, err
}
rawData, err = jsonRpc2Client.getRaw("updateAccount", &number, request)
} else {
cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "updateAccount", "-u", username}
rawData, err = s.cliClient.Execute(true, cmd, "")
}
var signalCliResp SetUsernameSignalCliResponse
err = json.Unmarshal([]byte(rawData), &signalCliResp)
if err != nil {
return resp, errors.New("Couldn't process request - invalid signal-cli response")
}
resp.Username = signalCliResp.Username
resp.UsernameLink = signalCliResp.UsernameLink
return resp, err
}
func (s *SignalClient) RemoveUsername(number string) error {
if s.signalCliMode == JsonRpc {
type Request struct {
DeleteUsername bool `json:"delete-username"`
}
request := Request{DeleteUsername: true}
jsonRpc2Client, err := s.getJsonRpc2Client()
if err != nil {
return err
}
_, err = jsonRpc2Client.getRaw("updateAccount", &number, request)
return err
} else {
cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "updateAccount", "--delete-username"}
_, err := s.cliClient.Execute(true, cmd, "")
return err
}
}
func (s *SignalClient) UpdateAccountSettings(number string, discoverableByNumber *bool, shareNumber *bool) error {
if s.signalCliMode == JsonRpc {
type Request struct {
ShareNumber *bool `json:"number-sharing"`
DiscoverableByNumber *bool `json:"discoverable-by-number"`
}
request := Request{}
request.DiscoverableByNumber = discoverableByNumber
request.ShareNumber = shareNumber
jsonRpc2Client, err := s.getJsonRpc2Client()
if err != nil {
return err
}
_, err = jsonRpc2Client.getRaw("updateAccount", &number, request)
return err
} else {
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateAccount"}
if discoverableByNumber != nil {
cmd = append(cmd, []string{"--discoverable-by-number", strconv.FormatBool(*discoverableByNumber)}...)
}
if shareNumber != nil {
cmd = append(cmd, []string{"--number-sharing", strconv.FormatBool(*shareNumber)}...)
}
_, err := s.cliClient.Execute(true, cmd, "")
return err
}
}

View File

@@ -116,6 +116,127 @@ var doc = `{
}
}
},
"/v1/accounts/{number}/settings": {
"put": {
"description": "Update the account attributes on the signal server.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Accounts"
],
"summary": "Update the account settings.",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
},
{
"description": "Request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.UpdateAccountSettingsRequest"
}
}
],
"responses": {
"204": {},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/v1/accounts/{number}/username": {
"post": {
"description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Accounts"
],
"summary": "Set a username.",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
},
{
"description": "Request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.SetUsernameRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/client.SetUsernameResponse"
}
},
"204": {},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
},
"delete": {
"description": "Delete the username associated with this account.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Accounts"
],
"summary": "Remove a username.",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
"204": {},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/v1/attachments": {
"get": {
"description": "List all downloaded attachments",
@@ -1964,6 +2085,14 @@ var doc = `{
}
}
},
"api.SetUsernameRequest": {
"type": "object",
"properties": {
"username": {
"type": "string"
}
}
},
"api.TrustIdentityRequest": {
"type": "object",
"properties": {
@@ -2013,6 +2142,17 @@ var doc = `{
}
}
},
"api.UpdateAccountSettingsRequest": {
"type": "object",
"properties": {
"discoverable_by_number": {
"type": "boolean"
},
"share_number": {
"type": "boolean"
}
}
},
"api.UpdateContactRequest": {
"type": "object",
"properties": {
@@ -2166,6 +2306,17 @@ var doc = `{
"type": "integer"
}
}
},
"client.SetUsernameResponse": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"username_link": {
"type": "string"
}
}
}
},
"tags": [

View File

@@ -100,6 +100,127 @@
}
}
},
"/v1/accounts/{number}/settings": {
"put": {
"description": "Update the account attributes on the signal server.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Accounts"
],
"summary": "Update the account settings.",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
},
{
"description": "Request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.UpdateAccountSettingsRequest"
}
}
],
"responses": {
"204": {},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/v1/accounts/{number}/username": {
"post": {
"description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Accounts"
],
"summary": "Set a username.",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
},
{
"description": "Request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.SetUsernameRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/client.SetUsernameResponse"
}
},
"204": {},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
},
"delete": {
"description": "Delete the username associated with this account.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Accounts"
],
"summary": "Remove a username.",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
"204": {},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.Error"
}
}
}
}
},
"/v1/attachments": {
"get": {
"description": "List all downloaded attachments",
@@ -1948,6 +2069,14 @@
}
}
},
"api.SetUsernameRequest": {
"type": "object",
"properties": {
"username": {
"type": "string"
}
}
},
"api.TrustIdentityRequest": {
"type": "object",
"properties": {
@@ -1997,6 +2126,17 @@
}
}
},
"api.UpdateAccountSettingsRequest": {
"type": "object",
"properties": {
"discoverable_by_number": {
"type": "boolean"
},
"share_number": {
"type": "boolean"
}
}
},
"api.UpdateContactRequest": {
"type": "object",
"properties": {
@@ -2150,6 +2290,17 @@
"type": "integer"
}
}
},
"client.SetUsernameResponse": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"username_link": {
"type": "string"
}
}
}
},
"tags": [

View File

@@ -168,6 +168,11 @@ definitions:
- styled
type: string
type: object
api.SetUsernameRequest:
properties:
username:
type: string
type: object
api.TrustIdentityRequest:
properties:
trust_all_known_keys:
@@ -200,6 +205,13 @@ definitions:
example: false
type: boolean
type: object
api.UpdateAccountSettingsRequest:
properties:
discoverable_by_number:
type: boolean
share_number:
type: boolean
type: object
api.UpdateContactRequest:
properties:
expiration_in_seconds:
@@ -300,6 +312,13 @@ definitions:
start:
type: integer
type: object
client.SetUsernameResponse:
properties:
username:
type: string
username_link:
type: string
type: object
info:
contact: {}
description: This is the Signal Cli REST API documentation.
@@ -367,6 +386,87 @@ paths:
summary: Lift rate limit restrictions by solving a captcha.
tags:
- Accounts
/v1/accounts/{number}/settings:
put:
consumes:
- application/json
description: Update the account attributes on the signal server.
parameters:
- description: Registered Phone Number
in: path
name: number
required: true
type: string
- description: Request
in: body
name: data
required: true
schema:
$ref: '#/definitions/api.UpdateAccountSettingsRequest'
produces:
- application/json
responses:
"204": {}
"400":
description: Bad Request
schema:
$ref: '#/definitions/api.Error'
summary: Update the account settings.
tags:
- Accounts
/v1/accounts/{number}/username:
delete:
consumes:
- application/json
description: Delete the username associated with this account.
parameters:
- description: Registered Phone Number
in: path
name: number
required: true
type: string
produces:
- application/json
responses:
"204": {}
"400":
description: Bad Request
schema:
$ref: '#/definitions/api.Error'
summary: Remove a username.
tags:
- Accounts
post:
consumes:
- application/json
description: Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.
parameters:
- description: Registered Phone Number
in: path
name: number
required: true
type: string
- description: Request
in: body
name: data
required: true
schema:
$ref: '#/definitions/api.SetUsernameRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/client.SetUsernameResponse'
"204": {}
"400":
description: Bad Request
schema:
$ref: '#/definitions/api.Error'
summary: Set a username.
tags:
- Accounts
/v1/attachments:
get:
description: List all downloaded attachments

View File

@@ -205,6 +205,9 @@ func main() {
{
accounts.GET("", api.GetAccounts)
accounts.POST(":number/rate-limit-challenge", api.SubmitRateLimitChallenge)
accounts.PUT(":number/settings", api.UpdateAccountSettings)
accounts.POST(":number/username", api.SetUsername)
accounts.DELETE(":number/username", api.RemoveUsername)
}
devices := v1.Group("devices")