@@ -2,6 +2,8 @@ package protocol
2
2
3
3
import (
4
4
"context"
5
+ "os"
6
+ "path/filepath"
5
7
"time"
6
8
7
9
"github.com/golang/protobuf/proto"
@@ -13,7 +15,9 @@ import (
13
15
"github.com/status-im/status-go/multiaccounts/settings"
14
16
"github.com/status-im/status-go/protocol/common"
15
17
"github.com/status-im/status-go/protocol/communities"
18
+ "github.com/status-im/status-go/protocol/encryption"
16
19
"github.com/status-im/status-go/protocol/protobuf"
20
+ v1protocol "github.com/status-im/status-go/protocol/v1"
17
21
)
18
22
19
23
const (
@@ -136,7 +140,7 @@ func (m *Messenger) BackupData(ctx context.Context) (uint64, error) {
136
140
},
137
141
ProfileDetails : & protobuf.FetchingBackedUpDataDetails {
138
142
DataNumber : uint32 (0 ),
139
- TotalNumber : uint32 (len ( profileToBackup )),
143
+ TotalNumber : uint32 (1 ), // Profile is always one
140
144
},
141
145
SettingsDetails : & protobuf.FetchingBackedUpDataDetails {
142
146
DataNumber : uint32 (0 ),
@@ -153,11 +157,14 @@ func (m *Messenger) BackupData(ctx context.Context) (uint64, error) {
153
157
}
154
158
}
155
159
160
+ fullBackup := & protobuf.Backup {}
161
+
156
162
// Update contacts messages encode and dispatch
157
163
for i , d := range contactsToBackup {
158
164
pb := backupDetailsOnly ()
159
165
pb .ContactsDetails .DataNumber = uint32 (i + 1 )
160
166
pb .Contacts = d .Contacts
167
+ fullBackup .Contacts = append (fullBackup .Contacts , d .Contacts ... )
161
168
err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
162
169
if err != nil {
163
170
return 0 , err
@@ -169,28 +176,29 @@ func (m *Messenger) BackupData(ctx context.Context) (uint64, error) {
169
176
pb := backupDetailsOnly ()
170
177
pb .CommunitiesDetails .DataNumber = uint32 (i + 1 )
171
178
pb .Communities = d .Communities
179
+ fullBackup .Communities = append (fullBackup .Communities , d .Communities ... )
172
180
err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
173
181
if err != nil {
174
182
return 0 , err
175
183
}
176
184
}
177
185
178
186
// Update profile messages encode and dispatch
179
- for i , d := range profileToBackup {
180
- pb := backupDetailsOnly ()
181
- pb .ProfileDetails .DataNumber = uint32 (i + 1 )
182
- pb .Profile = d .Profile
183
- err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
184
- if err != nil {
185
- return 0 , err
186
- }
187
+ pb := backupDetailsOnly ()
188
+ pb .ProfileDetails .DataNumber = uint32 (1 )
189
+ pb .Profile = profileToBackup .Profile
190
+ fullBackup .Profile = profileToBackup .Profile
191
+ err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
192
+ if err != nil {
193
+ return 0 , err
187
194
}
188
195
189
196
// Update chats encode and dispatch
190
197
for i , d := range chatsToBackup {
191
198
pb := backupDetailsOnly ()
192
199
pb .ChatsDetails .DataNumber = uint32 (i + 1 )
193
200
pb .Chats = d .Chats
201
+ fullBackup .Chats = append (fullBackup .Chats , d .Chats ... )
194
202
err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
195
203
if err != nil {
196
204
return 0 , err
@@ -202,6 +210,8 @@ func (m *Messenger) BackupData(ctx context.Context) (uint64, error) {
202
210
pb := backupDetailsOnly ()
203
211
pb .SettingsDetails .DataNumber = uint32 (i + 1 )
204
212
pb .Setting = d
213
+ // TODO find a way to get all settings
214
+ // fullBackup.Setting = append(fullBackup.Setting, d)
205
215
err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
206
216
if err != nil {
207
217
return 0 , err
@@ -213,6 +223,8 @@ func (m *Messenger) BackupData(ctx context.Context) (uint64, error) {
213
223
pb := backupDetailsOnly ()
214
224
pb .KeypairDetails .DataNumber = uint32 (i + 1 )
215
225
pb .Keypair = d .Keypair
226
+ // TODO find a way to get all settings
227
+ // fullBackup.Keypair = append(fullBackup.Keypair, d.Keypair)
216
228
err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
217
229
if err != nil {
218
230
return 0 , err
@@ -224,12 +236,49 @@ func (m *Messenger) BackupData(ctx context.Context) (uint64, error) {
224
236
pb := backupDetailsOnly ()
225
237
pb .WatchOnlyAccountDetails .DataNumber = uint32 (i + 1 )
226
238
pb .WatchOnlyAccount = d .WatchOnlyAccount
239
+ // TODO find a way to get all settings
240
+ // fullBackup.WatchOnlyAccount = append(fullBackup.WatchOnlyAccount, d.Keypair)
227
241
err = m .encodeAndDispatchBackupMessage (ctx , pb , chat .ID )
228
242
if err != nil {
229
243
return 0 , err
230
244
}
231
245
}
232
246
247
+ if m .config .featureFlags .EnableLocalBackup {
248
+ // TODO put file in a constant
249
+ path := filepath .Join (m .config .backupConfig .DataDir , "user_data.bkp" )
250
+
251
+ if err := os .MkdirAll (m .config .backupConfig .DataDir , 0700 ); err != nil {
252
+ return 0 , err
253
+ }
254
+
255
+ file , err := os .Create (path )
256
+ if err != nil {
257
+ return 0 , err
258
+ }
259
+ defer file .Close ()
260
+
261
+ mashalledMessage , err := proto .Marshal (fullBackup )
262
+ if err != nil {
263
+ return 0 , err
264
+ }
265
+
266
+ messageSpec , err := m .encryptor .BuildDHMessage (m .identity , & m .identity .PublicKey , mashalledMessage )
267
+ if err != nil {
268
+ return 0 , err
269
+ }
270
+
271
+ encryptedMessage , err := proto .Marshal (messageSpec .Message )
272
+ if err != nil {
273
+ return 0 , err
274
+ }
275
+ err = os .WriteFile (path , encryptedMessage , 0600 )
276
+ if err != nil {
277
+ m .logger .Error ("failed to write backup message to file" , zap .Error (err ), zap .String ("path" , path ))
278
+ return 0 , err
279
+ }
280
+ }
281
+
233
282
chat .LastClockValue = clock
234
283
err = m .saveChat (chat )
235
284
if err != nil {
@@ -248,6 +297,62 @@ func (m *Messenger) BackupData(ctx context.Context) (uint64, error) {
248
297
return clockInSeconds , nil
249
298
}
250
299
300
+ func (m * Messenger ) importLocalBackupFile (filePath string ) (* MessengerResponse , error ) {
301
+ if ! m .config .featureFlags .EnableLocalBackup {
302
+ return nil , nil
303
+ }
304
+
305
+ // Make sure the backup file exists
306
+ content , err := os .ReadFile (filePath )
307
+ if err != nil {
308
+ return nil , err
309
+ }
310
+
311
+ // Decrypt the backup file
312
+ // Unmarshal the content to get the message spec
313
+ var messageSpec encryption.ProtocolMessage
314
+ err = proto .Unmarshal (content , & messageSpec )
315
+ if err != nil {
316
+ return nil , err
317
+ }
318
+
319
+ // Decrypt the payload
320
+ var defaultMessageID = []byte ("default" )
321
+ decryptedPayload1 , err := m .encryptor .HandleMessage (m .identity , & m .identity .PublicKey , & messageSpec , defaultMessageID )
322
+ if err != nil {
323
+ return nil , err
324
+ }
325
+
326
+ // Unmarshal the decrypted payload to get the backup message
327
+ var backupMessage protobuf.Backup
328
+ err = proto .Unmarshal (decryptedPayload1 .DecryptedMessage , & backupMessage )
329
+ if err != nil {
330
+ return nil , err
331
+ }
332
+
333
+ // Handle the backup
334
+ state := ReceivedMessageState {
335
+ Response : & MessengerResponse {},
336
+ AllChats : & chatMap {},
337
+ AllContacts : & contactMap {
338
+ me : m .selfContact ,
339
+ },
340
+ Timesource : m .getTimesource (),
341
+ ModifiedContacts : & stringBoolMap {},
342
+ ModifiedInstallations : & stringBoolMap {},
343
+ }
344
+ err = m .HandleBackup (
345
+ & state ,
346
+ & backupMessage ,
347
+ & v1protocol.StatusMessage {},
348
+ )
349
+ if err != nil {
350
+ return nil , err
351
+ }
352
+
353
+ return m .saveDataAndPrepareResponse (& state )
354
+ }
355
+
251
356
func (m * Messenger ) encodeAndDispatchBackupMessage (ctx context.Context , message * protobuf.Backup , chatID string ) error {
252
357
encodedMessage , err := proto .Marshal (message )
253
358
if err != nil {
@@ -447,7 +552,7 @@ func (m *Messenger) buildSyncContactMessage(contact *Contact) *protobuf.SyncInst
447
552
}
448
553
}
449
554
450
- func (m * Messenger ) backupProfile (ctx context.Context , clock uint64 ) ([] * protobuf.Backup , error ) {
555
+ func (m * Messenger ) backupProfile (ctx context.Context , clock uint64 ) (* protobuf.Backup , error ) {
451
556
displayName , err := m .settings .DisplayName ()
452
557
if err != nil {
453
558
return nil , err
@@ -515,9 +620,7 @@ func (m *Messenger) backupProfile(ctx context.Context, clock uint64) ([]*protobu
515
620
},
516
621
}
517
622
518
- backupMessages := []* protobuf.Backup {backupMessage }
519
-
520
- return backupMessages , nil
623
+ return backupMessage , nil
521
624
}
522
625
523
626
func (m * Messenger ) backupKeypairs () ([]* protobuf.Backup , error ) {
0 commit comments