Update protocol

This commit is contained in:
Finn 2021-07-08 23:56:58 -07:00
parent 8d38d54615
commit fdcaabfba4
5 changed files with 232 additions and 5 deletions

View file

@ -2,9 +2,9 @@
"doc_version": "v1", "doc_version": "v1",
"version": { "version": {
"name": "signald", "name": "signald",
"version": "0.13.1+git2021-07-02r158383d6.37", "version": "0.13.1+git2021-07-09rabe585d6.42",
"branch": "main", "branch": "main",
"commit": "158383d66c48fc1aa4df4dfe77181f709bc8775a" "commit": "abe585d68fdb00b440c1b0c517e1ece2bc095ba3"
}, },
"info": "This document describes objects that may be used when communicating with signald.", "info": "This document describes objects that may be used when communicating with signald.",
"types": { "types": {
@ -256,7 +256,7 @@
}, },
"version": { "version": {
"type": "String", "type": "String",
"example": "\"0.13.1+git2021-07-02r158383d6.37\"" "example": "\"0.13.1+git2021-07-09rabe585d6.42\""
}, },
"branch": { "branch": {
"type": "String", "type": "String",
@ -264,7 +264,7 @@
}, },
"commit": { "commit": {
"type": "String", "type": "String",
"example": "\"158383d66c48fc1aa4df4dfe77181f709bc8775a\"" "example": "\"abe585d68fdb00b440c1b0c517e1ece2bc095ba3\""
} }
} }
}, },
@ -778,7 +778,12 @@
} }
}, },
"GenerateLinkingURIRequest": { "GenerateLinkingURIRequest": {
"fields": {}, "fields": {
"server": {
"type": "String",
"doc": "The identifier of the server to use. Leave blank for default (usually Signal production servers but configurable at build time)"
}
},
"doc": "Generate a linking URI. Typically this is QR encoded and scanned by the primary device. Submit the returned session_id with a finish_link request." "doc": "Generate a linking URI. Typically this is QR encoded and scanned by the primary device. Submit the returned session_id with a finish_link request."
}, },
"LinkingURI": { "LinkingURI": {
@ -852,6 +857,10 @@
"captcha": { "captcha": {
"type": "String", "type": "String",
"doc": "See https://signald.org/articles/captcha/" "doc": "See https://signald.org/articles/captcha/"
},
"server": {
"type": "String",
"doc": "The identifier of the server to use. Leave blank for default (usually Signal production servers but configurable at build time)"
} }
}, },
"doc": "begin the account registration process by requesting a phone number verification code. when the code is received, submit it with a verify request" "doc": "begin the account registration process by requesting a phone number verification code. when the code is received, submit it with a verify request"
@ -1183,6 +1192,35 @@
}, },
"doc": "delete a message previously sent" "doc": "delete a message previously sent"
}, },
"AddServerRequest": {
"fields": {
"server": {
"type": "Server",
"version": "v1",
"required": true
}
},
"doc": "add a new server to connect to. Returns the new server's UUID."
},
"GetServersRequest": {
"fields": {}
},
"ServerList": {
"fields": {
"servers": {
"list": true,
"type": "Server",
"version": "v1"
}
}
},
"RemoveServerRequest": {
"fields": {
"uuid": {
"type": "String"
}
}
},
"JsonDataMessage": { "JsonDataMessage": {
"fields": { "fields": {
"timestamp": { "timestamp": {
@ -1590,6 +1628,45 @@
} }
} }
}, },
"Server": {
"fields": {
"uuid": {
"type": "UUID",
"doc": "A unique identifier for the server, referenced when adding accounts. Must be a valid UUID. Will be generated if not specified when creating."
},
"proxy": {
"type": "String"
},
"ca": {
"type": "String"
},
"service_url": {
"type": "String"
},
"cdn_urls": {
"list": true,
"type": "ServerCDN",
"version": "v1"
},
"contact_discovery_url": {
"type": "String"
},
"key_backup_url": {
"type": "String"
},
"storage_url": {
"type": "String"
},
"zk_param": {
"type": "String",
"doc": "base64 encoded ZKGROUP_SERVER_PUBLIC_PARAMS value"
},
"unidentified_sender_root": {
"type": "String"
}
},
"doc": "a Signal server"
},
"RemoteDelete": { "RemoteDelete": {
"fields": { "fields": {
"target_sent_timestamp": { "target_sent_timestamp": {
@ -1767,6 +1844,9 @@
"type": "String" "type": "String"
} }
} }
},
"ServerCDN": {
"fields": {}
} }
}, },
"v0": { "v0": {
@ -2201,6 +2281,9 @@
"attachment": { "attachment": {
"type": "JsonAttachment", "type": "JsonAttachment",
"version": "v0" "version": "v0"
},
"image": {
"type": "String"
} }
}, },
"deprecated": true, "deprecated": true,
@ -2868,6 +2951,18 @@
"request": "RemoteDeleteRequest", "request": "RemoteDeleteRequest",
"response": "SendResponse", "response": "SendResponse",
"doc": "delete a message previously sent" "doc": "delete a message previously sent"
},
"add_server": {
"request": "AddServerRequest",
"response": "String",
"doc": "add a new server to connect to. Returns the new server's UUID."
},
"get_servers": {
"request": "GetServersRequest",
"response": "ServerList"
},
"delete_server": {
"request": "RemoveServerRequest"
} }
} }
} }

View file

@ -228,6 +228,7 @@ type JsonSentTranscriptMessage struct {
type JsonSticker struct { type JsonSticker struct {
Attachment *JsonAttachment `json:"attachment,omitempty" yaml:"attachment,omitempty"` Attachment *JsonAttachment `json:"attachment,omitempty" yaml:"attachment,omitempty"`
Image string `json:"image,omitempty" yaml:"image,omitempty"`
PackID string `json:"packID,omitempty" yaml:"packID,omitempty"` PackID string `json:"packID,omitempty" yaml:"packID,omitempty"`
PackKey string `json:"packKey,omitempty" yaml:"packKey,omitempty"` PackKey string `json:"packKey,omitempty" yaml:"packKey,omitempty"`
StickerID int32 `json:"stickerID,omitempty" yaml:"stickerID,omitempty"` StickerID int32 `json:"stickerID,omitempty" yaml:"stickerID,omitempty"`

View file

@ -69,6 +69,39 @@ func (r *AddLinkedDeviceRequest) Submit(conn *signald.Signald) (err error) {
} }
// Submit: add a new server to connect to. Returns the new server's UUID.
func (r *AddServerRequest) Submit(conn *signald.Signald) (response string, err error) {
r.Version = "v1"
r.Type = "add_server"
if r.ID == "" {
r.ID = signald.GenerateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return
}
return response, nil
}
// Submit: approve a request to join a group // Submit: approve a request to join a group
func (r *ApproveMembershipRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) { func (r *ApproveMembershipRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1" r.Version = "v1"
@ -160,6 +193,31 @@ func (r *DeleteAccountRequest) Submit(conn *signald.Signald) (err error) {
} }
func (r *RemoveServerRequest) Submit(conn *signald.Signald) (err error) {
r.Version = "v1"
r.Type = "delete_server"
if r.ID == "" {
r.ID = signald.GenerateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
return err
}
// Submit: After a linking URI has been requested, finish_link must be called with the session_id provided with the URI. it will return information about the new account once the linking process is completed by the other device. // Submit: After a linking URI has been requested, finish_link must be called with the session_id provided with the URI. it will return information about the new account once the linking process is completed by the other device.
func (r *FinishLinkRequest) Submit(conn *signald.Signald) (response Account, err error) { func (r *FinishLinkRequest) Submit(conn *signald.Signald) (response Account, err error) {
r.Version = "v1" r.Version = "v1"
@ -391,6 +449,38 @@ func (r *GetProfileRequest) Submit(conn *signald.Signald) (response Profile, err
} }
func (r *GetServersRequest) Submit(conn *signald.Signald) (response ServerList, err error) {
r.Version = "v1"
r.Type = "get_servers"
if r.ID == "" {
r.ID = signald.GenerateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return
}
return response, nil
}
// Submit: Get information about a group from a signal.group link // Submit: Get information about a group from a signal.group link
func (r *GroupLinkInfoRequest) Submit(conn *signald.Signald) (response JsonGroupJoinInfo, err error) { func (r *GroupLinkInfoRequest) Submit(conn *signald.Signald) (response JsonGroupJoinInfo, err error) {
r.Version = "v1" r.Version = "v1"

View file

@ -37,6 +37,12 @@ type AddLinkedDeviceRequest struct {
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"` // the tsdevice:/ uri provided (typically in qr code form) by the new device Uri string `json:"uri,omitempty" yaml:"uri,omitempty"` // the tsdevice:/ uri provided (typically in qr code form) by the new device
} }
// AddServerRequest: add a new server to connect to. Returns the new server's UUID.
type AddServerRequest struct {
Request
Server *Server `json:"server,omitempty" yaml:"server,omitempty"`
}
type AllIdentityKeyList struct { type AllIdentityKeyList struct {
IdentityKeys []*IdentityKeyList `json:"identity_keys,omitempty" yaml:"identity_keys,omitempty"` IdentityKeys []*IdentityKeyList `json:"identity_keys,omitempty" yaml:"identity_keys,omitempty"`
} }
@ -117,6 +123,7 @@ type FinishLinkRequest struct {
// GenerateLinkingURIRequest: Generate a linking URI. Typically this is QR encoded and scanned by the primary device. Submit the returned session_id with a finish_link request. // GenerateLinkingURIRequest: Generate a linking URI. Typically this is QR encoded and scanned by the primary device. Submit the returned session_id with a finish_link request.
type GenerateLinkingURIRequest struct { type GenerateLinkingURIRequest struct {
Request Request
Server string `json:"server,omitempty" yaml:"server,omitempty"` // The identifier of the server to use. Leave blank for default (usually Signal production servers but configurable at build time)
} }
// GetAllIdentities: get all known identity keys // GetAllIdentities: get all known identity keys
@ -154,6 +161,10 @@ type GetProfileRequest struct {
Async bool `json:"async,omitempty" yaml:"async,omitempty"` // if true, return results from local store immediately, refreshing from server in the background if needed. if false (default), block until profile can be retrieved from server Async bool `json:"async,omitempty" yaml:"async,omitempty"` // if true, return results from local store immediately, refreshing from server in the background if needed. if false (default), block until profile can be retrieved from server
} }
type GetServersRequest struct {
Request
}
// GroupAccessControl: group access control settings. Options for each controlled action are: UNKNOWN, ANY, MEMBER, ADMINISTRATOR, UNSATISFIABLE and UNRECOGNIZED // GroupAccessControl: group access control settings. Options for each controlled action are: UNKNOWN, ANY, MEMBER, ADMINISTRATOR, UNSATISFIABLE and UNRECOGNIZED
type GroupAccessControl struct { type GroupAccessControl struct {
Attributes string `json:"attributes,omitempty" yaml:"attributes,omitempty"` // who can edit group info Attributes string `json:"attributes,omitempty" yaml:"attributes,omitempty"` // who can edit group info
@ -506,6 +517,7 @@ type RegisterRequest struct {
Request Request
Account string `json:"account,omitempty" yaml:"account,omitempty"` // the e164 phone number to register with Account string `json:"account,omitempty" yaml:"account,omitempty"` // the e164 phone number to register with
Captcha string `json:"captcha,omitempty" yaml:"captcha,omitempty"` // See https://signald.org/articles/captcha/ Captcha string `json:"captcha,omitempty" yaml:"captcha,omitempty"` // See https://signald.org/articles/captcha/
Server string `json:"server,omitempty" yaml:"server,omitempty"` // The identifier of the server to use. Leave blank for default (usually Signal production servers but configurable at build time)
Voice bool `json:"voice,omitempty" yaml:"voice,omitempty"` // set to true to request a voice call instead of an SMS for verification Voice bool `json:"voice,omitempty" yaml:"voice,omitempty"` // set to true to request a voice call instead of an SMS for verification
} }
@ -529,6 +541,11 @@ type RemoveLinkedDeviceRequest struct {
DeviceId int64 `json:"deviceId,omitempty" yaml:"deviceId,omitempty"` // the ID of the device to unlink DeviceId int64 `json:"deviceId,omitempty" yaml:"deviceId,omitempty"` // the ID of the device to unlink
} }
type RemoveServerRequest struct {
Request
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
}
// RequestSyncRequest: Request other devices on the account send us their group list, syncable config and contact list. // RequestSyncRequest: Request other devices on the account send us their group list, syncable config and contact list.
type RequestSyncRequest struct { type RequestSyncRequest struct {
Request Request
@ -571,6 +588,27 @@ type SendResponse struct {
Timestamp int64 `json:"timestamp,omitempty" yaml:"timestamp,omitempty"` Timestamp int64 `json:"timestamp,omitempty" yaml:"timestamp,omitempty"`
} }
// Server: a Signal server
type Server struct {
Ca string `json:"ca,omitempty" yaml:"ca,omitempty"`
CdnUrls []*ServerCDN `json:"cdn_urls,omitempty" yaml:"cdn_urls,omitempty"`
ContactDiscoveryUrl string `json:"contact_discovery_url,omitempty" yaml:"contact_discovery_url,omitempty"`
KeyBackupUrl string `json:"key_backup_url,omitempty" yaml:"key_backup_url,omitempty"`
Proxy string `json:"proxy,omitempty" yaml:"proxy,omitempty"`
ServiceUrl string `json:"service_url,omitempty" yaml:"service_url,omitempty"`
StorageUrl string `json:"storage_url,omitempty" yaml:"storage_url,omitempty"`
UnidentifiedSenderRoot string `json:"unidentified_sender_root,omitempty" yaml:"unidentified_sender_root,omitempty"`
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` // A unique identifier for the server, referenced when adding accounts. Must be a valid UUID. Will be generated if not specified when creating.
ZkParam string `json:"zk_param,omitempty" yaml:"zk_param,omitempty"` // base64 encoded ZKGROUP_SERVER_PUBLIC_PARAMS value
}
type ServerCDN struct {
}
type ServerList struct {
Servers []*Server `json:"servers,omitempty" yaml:"servers,omitempty"`
}
// SetDeviceNameRequest: set this device's name. This will show up on the mobile device on the same account under // SetDeviceNameRequest: set this device's name. This will show up on the mobile device on the same account under
type SetDeviceNameRequest struct { type SetDeviceNameRequest struct {
Request Request

View file

@ -34,6 +34,9 @@ import (
const ( const (
defaultSocketPrefix = "/var/run" defaultSocketPrefix = "/var/run"
socketSuffix = "/signald/signald.sock" socketSuffix = "/signald/signald.sock"
ProductionServerUUID = "6e2eb5a8-5706-45d0-8377-127a816411a4"
StagingServerUUID = "97c17f0c-e53b-426f-8ffa-c052d4183f83"
) )
var ( var (