@@ -232,6 +232,7 @@ type ListContactsResponse struct {
232232}
233233
234234type ListDevicesResponse struct {
235+ Id int64 `json:"id"`
235236 Name string `json:"name"`
236237 LastSeenTimestamp int64 `json:"last_seen_timestamp"`
237238 CreationTimestamp int64 `json:"creation_timestamp"`
@@ -783,6 +784,32 @@ func (s *SignalClient) UnregisterNumber(number string, deleteAccount bool, delet
783784 return err
784785}
785786
787+ func (s * SignalClient ) DeleteLocalAccountData (number string , ignoreRegistered bool ) error {
788+ if s .signalCliMode == JsonRpc {
789+ type Request struct {
790+ IgnoreRegistered bool `json:"ignore-registered,omitempty"`
791+ }
792+ req := Request {}
793+ if ignoreRegistered {
794+ req .IgnoreRegistered = true
795+ }
796+
797+ jsonRpc2Client , err := s .getJsonRpc2Client ()
798+ if err != nil {
799+ return err
800+ }
801+ _ , err = jsonRpc2Client .getRaw ("deleteLocalAccountData" , & number , req )
802+ return err
803+ } else {
804+ cmd := []string {"--config" , s .signalCliConfig , "-a" , number , "deleteLocalAccountData" }
805+ if ignoreRegistered {
806+ cmd = append (cmd , "--ignore-registered" )
807+ }
808+ _ , err := s .cliClient .Execute (true , cmd , "" )
809+ return err
810+ }
811+ }
812+
786813func (s * SignalClient ) VerifyRegisteredNumber (number string , token string , pin string ) error {
787814 if s .signalCliMode == JsonRpc {
788815 type Request struct {
@@ -1463,25 +1490,7 @@ func (s *SignalClient) GetQrCodeLink(deviceName string, qrCodeVersion int) ([]by
14631490 return []byte {}, errors .New ("Couldn't create QR code: " + err .Error ())
14641491 }
14651492
1466- go (func () {
1467- type FinishRequest struct {
1468- DeviceLinkUri string `json:"deviceLinkUri"`
1469- DeviceName string `json:"deviceName"`
1470- }
1471-
1472- req := FinishRequest {
1473- DeviceLinkUri : resp .DeviceLinkUri ,
1474- DeviceName : deviceName ,
1475- }
1476-
1477- result , err := jsonRpc2Client .getRaw ("finishLink" , nil , & req )
1478- if err != nil {
1479- log .Debug ("Error linking device: " , err .Error ())
1480- return
1481- }
1482- log .Debug ("Linking device result: " , result )
1483- s .signalCliApiConfig .Load (s .signalCliApiConfigPath )
1484- })()
1493+ s .finishLinkAsync (jsonRpc2Client , deviceName , resp .DeviceLinkUri )
14851494
14861495 return png , nil
14871496 }
@@ -1506,6 +1515,57 @@ func (s *SignalClient) GetQrCodeLink(deviceName string, qrCodeVersion int) ([]by
15061515 return png , nil
15071516}
15081517
1518+ func (s * SignalClient ) GetDeviceLinkUri (deviceName string ) (string , error ) {
1519+ if s .signalCliMode == JsonRpc {
1520+ type StartResponse struct {
1521+ DeviceLinkUri string `json:"deviceLinkUri"`
1522+ }
1523+ jsonRpc2Client , err := s .getJsonRpc2Client ()
1524+ if err != nil {
1525+ return "" , err
1526+ }
1527+
1528+ raw , err := jsonRpc2Client .getRaw ("startLink" , nil , struct {}{})
1529+ if err != nil {
1530+ return "" , errors .New ("Couldn't start link: " + err .Error ())
1531+ }
1532+
1533+ var resp StartResponse
1534+ if err := json .Unmarshal ([]byte (raw ), & resp ); err != nil {
1535+ return "" , errors .New ("Couldn't parse startLink response: " + err .Error ())
1536+ }
1537+
1538+ // Complete the linking handshake in the background, just like GetQrCodeLink does.
1539+ s .finishLinkAsync (jsonRpc2Client , deviceName , resp .DeviceLinkUri )
1540+ return resp .DeviceLinkUri , nil
1541+ }
1542+
1543+ cmd := []string {"--config" , s .signalCliConfig , "link" , "-n" , deviceName }
1544+ deviceLinkUri , err := s .cliClient .Execute (false , cmd , "" )
1545+ if err != nil {
1546+ return "" , errors .New ("Couldn't create link URI: " + err .Error ())
1547+ }
1548+ return strings .TrimSpace (deviceLinkUri ), nil
1549+ }
1550+
1551+ func (s * SignalClient ) finishLinkAsync (jsonRpc2Client * JsonRpc2Client , deviceName string , deviceLinkUri string ) {
1552+ type finishRequest struct {
1553+ DeviceLinkUri string `json:"deviceLinkUri"`
1554+ DeviceName string `json:"deviceName"`
1555+ }
1556+
1557+ go func () {
1558+ req := finishRequest {DeviceLinkUri : deviceLinkUri , DeviceName : deviceName }
1559+ result , err := jsonRpc2Client .getRaw ("finishLink" , nil , & req )
1560+ if err != nil {
1561+ log .Debug ("Error linking device: " , err .Error ())
1562+ return
1563+ }
1564+ log .Debug ("Linking device result: " , result )
1565+ s .signalCliApiConfig .Load (s .signalCliApiConfigPath )
1566+ }()
1567+ }
1568+
15091569func (s * SignalClient ) GetAccounts () ([]string , error ) {
15101570 accounts := make ([]string , 0 )
15111571 var rawData string
@@ -2285,6 +2345,7 @@ func (s *SignalClient) ListDevices(number string) ([]ListDevicesResponse, error)
22852345
22862346 for _ , entry := range signalCliResp {
22872347 deviceEntry := ListDevicesResponse {
2348+ Id : entry .Id ,
22882349 Name : entry .Name ,
22892350 CreationTimestamp : entry .CreatedTimestamp ,
22902351 LastSeenTimestamp : entry .LastSeenTimestamp ,
@@ -2295,6 +2356,25 @@ func (s *SignalClient) ListDevices(number string) ([]ListDevicesResponse, error)
22952356 return resp , nil
22962357}
22972358
2359+ func (s * SignalClient ) RemoveDevice (number string , deviceId int64 ) error {
2360+ var err error
2361+ if s .signalCliMode == JsonRpc {
2362+ type Request struct {
2363+ DeviceId int64 `json:"deviceId"`
2364+ }
2365+ request := Request {DeviceId : deviceId }
2366+ jsonRpc2Client , err := s .getJsonRpc2Client ()
2367+ if err != nil {
2368+ return err
2369+ }
2370+ _ , err = jsonRpc2Client .getRaw ("removeDevice" , & number , request )
2371+ } else {
2372+ cmd := []string {"--config" , s .signalCliConfig , "-a" , number , "removeDevice" , "--deviceId" , strconv .FormatInt (deviceId , 10 )}
2373+ _ , err = s .cliClient .Execute (true , cmd , "" )
2374+ }
2375+ return err
2376+ }
2377+
22982378func (s * SignalClient ) SetTrustMode (number string , trustMode utils.SignalCliTrustMode ) error {
22992379 if s .signalCliMode == JsonRpc {
23002380 return errors .New ("Not supported in json-rpc mode, use the environment variable JSON_RPC_TRUST_NEW_IDENTITIES instead!" )
0 commit comments