Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: bitmark-inc/feralfile-app
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4ce695136be6ac9bce014d7da115e776393ab534
Choose a base ref
..
head repository: bitmark-inc/feralfile-app
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e7937a613a002a1b4b322862665a7acae5f65d8f
Choose a head ref
7 changes: 3 additions & 4 deletions lib/database/dao/firestore_address_dao.dart
Original file line number Diff line number Diff line change
@@ -35,11 +35,10 @@ abstract class FirestoreWalletAddressDao {

class FirestoreWalletAddressDaoImp implements FirestoreWalletAddressDao {
CloudFirestoreService firestoreService;
final _collectionName = 'wallet_address';
final _collection = FirestoreCollection.walletAddress;

CollectionReference<WalletAddress> get _collectionRef => firestoreService
.getCollection(_collectionName)
.withConverter<WalletAddress>(
CollectionReference<WalletAddress> get _collectionRef =>
firestoreService.getCollection(_collection).withConverter<WalletAddress>(
fromFirestore: (snapshot, _) =>
WalletAddress.fromJson(snapshot.data()!),
toFirestore: (address, _) => address.toJson());
4 changes: 2 additions & 2 deletions lib/database/dao/firestore_audit_dao.dart
Original file line number Diff line number Diff line change
@@ -22,11 +22,11 @@ abstract class FirestoreAuditDao {
}

class FirestoreAuditDaoImp implements FirestoreAuditDao {
final _collectionName = 'audit';
final _collection = FirestoreCollection.audit;
final CloudFirestoreService firestoreService;

CollectionReference<Audit> get _collectionRef =>
firestoreService.getCollection(_collectionName).withConverter<Audit>(
firestoreService.getCollection(_collection).withConverter<Audit>(
fromFirestore: (snapshot, _) => Audit.fromJson(snapshot.data()!),
toFirestore: (audit, _) => audit.toJson());

4 changes: 2 additions & 2 deletions lib/database/dao/firestore_connection_dao.dart
Original file line number Diff line number Diff line change
@@ -44,11 +44,11 @@ abstract class FirestoreConnectionDao {
}

class FirestoreConnectionDaoImp implements FirestoreConnectionDao {
final _collectionName = 'connection';
final _collection = FirestoreCollection.connection;
CloudFirestoreService firestoreService;

CollectionReference<Connection> get _collectionRef =>
firestoreService.getCollection(_collectionName).withConverter<Connection>(
firestoreService.getCollection(_collection).withConverter<Connection>(
fromFirestore: (snapshot, _) => Connection.fromJson(snapshot.data()!),
toFirestore: (connection, _) => connection.toJson());

4 changes: 2 additions & 2 deletions lib/database/dao/firestore_persona_dao.dart
Original file line number Diff line number Diff line change
@@ -31,10 +31,10 @@ abstract class FirestorePersonaDao {

class FirestorePersonaDaoImp implements FirestorePersonaDao {
CloudFirestoreService firestoreService;
final _collectionName = 'persona';
final _collection = FirestoreCollection.persona;

CollectionReference<Persona> get _collectionRef =>
firestoreService.getCollection(_collectionName).withConverter<Persona>(
firestoreService.getCollection(_collection).withConverter<Persona>(
fromFirestore: (snapshot, _) => Persona.fromJson(snapshot.data()!),
toFirestore: (persona, _) => persona.toJson());

29 changes: 21 additions & 8 deletions lib/screen/bloc/router/router_bloc.dart
Original file line number Diff line number Diff line change
@@ -45,7 +45,12 @@ class RouterBloc extends AuBloc<RouterEvent, RouterState> {
this._backupService)
: super(RouterState(onboardingStep: OnboardingStep.undefined)) {
final migrationUtil = MigrationUtil(
_configurationService, _cloudFirestoreDB, _iapService, _auditService);
_configurationService,
_cloudFirestoreDB,
_iapService,
_auditService,
_backupService,
_accountService);

on<DefineViewRoutingEvent>((event, emit) async {
if (state.onboardingStep != OnboardingStep.undefined) {
@@ -68,13 +73,21 @@ class RouterBloc extends AuBloc<RouterEvent, RouterState> {

if (await hasAccounts()) {
unawaited(_configurationService.setOldUser());
// add(RestoreCloudDatabaseRoutingEvent(version))
await _configurationService.setDoneOnboarding(true);
unawaited(injector<MetricClientService>()
.mixPanelClient
.initIfDefaultAccount());
emit(RouterState(onboardingStep: OnboardingStep.dashboard));
return;
final backupVersion = await _backupService
.fetchBackupVersion(await _accountService.getDefaultAccount());
if (backupVersion.isNotEmpty) {
emit(RouterState(
onboardingStep: OnboardingStep.restore,
backupVersion: backupVersion));
add(RestoreCloudDatabaseRoutingEvent(backupVersion));
} else {
await _configurationService.setDoneOnboarding(true);
unawaited(injector<MetricClientService>()
.mixPanelClient
.initIfDefaultAccount());
emit(RouterState(onboardingStep: OnboardingStep.dashboard));
return;
}
} else {
emit(RouterState(onboardingStep: OnboardingStep.startScreen));
}
30 changes: 20 additions & 10 deletions lib/service/account_service.dart
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ import 'package:autonomy_flutter/screen/bloc/scan_wallet/scan_wallet_state.dart'
import 'package:autonomy_flutter/service/audit_service.dart';
import 'package:autonomy_flutter/service/autonomy_service.dart';
import 'package:autonomy_flutter/service/configuration_service.dart';
import 'package:autonomy_flutter/service/iap_service.dart';
import 'package:autonomy_flutter/service/metric_client_service.dart';
import 'package:autonomy_flutter/service/navigation_service.dart';
import 'package:autonomy_flutter/service/settings_data_service.dart';
@@ -116,6 +115,8 @@ class AccountServiceImpl extends AccountService {
final AutonomyService _autonomyService;
final AddressService _addressService;

late MigrationUtil _migrationUtil;

final _defaultAccountLock = Lock();

AccountServiceImpl(
@@ -125,7 +126,16 @@ class AccountServiceImpl extends AccountService {
this._auditService,
this._autonomyService,
this._addressService,
);
) {
_migrationUtil = MigrationUtil(
_configurationService,
_cloudFDB,
injector(),
_auditService,
injector(),
injector(),
);
}

@override
Future<Persona> createPersona(
@@ -185,8 +195,13 @@ class AccountServiceImpl extends AccountService {

if (personas.isEmpty) {
await MigrationUtil(
_configurationService, _cloudFDB, injector(), _auditService)
.migrationFromKeychain();
_configurationService,
_cloudFDB,
injector(),
_auditService,
injector(),
injector(),
).migrationFromKeychain();
await androidRestoreKeys();

await Future.delayed(const Duration(seconds: 1));
@@ -701,13 +716,8 @@ class AccountServiceImpl extends AccountService {
if (_configurationService.isDoneOnboarding()) {
return;
}

final iapService = injector<IAPService>();
final auditService = injector<AuditService>();
final migrationUtil = MigrationUtil(
_configurationService, _cloudFDB, iapService, auditService);
await androidBackupKeys();
await migrationUtil.migrationFromKeychain();
await _migrationUtil.migrationFromKeychain();
final personas = await _cloudFDB.personaDao.getPersonas();
final connections = await _cloudFDB.connectionDao.getConnections();
if (personas.isNotEmpty || connections.isNotEmpty) {
55 changes: 54 additions & 1 deletion lib/service/backup_service.dart
Original file line number Diff line number Diff line change
@@ -6,14 +6,18 @@
//

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:autonomy_flutter/common/environment.dart';
import 'package:autonomy_flutter/common/injector.dart';
import 'package:autonomy_flutter/database/sqlite_cloud_database.dart';
import 'package:autonomy_flutter/gateway/iap_api.dart';
import 'package:autonomy_flutter/model/backup_versions.dart';
import 'package:autonomy_flutter/service/cloud_firestore_service.dart';
import 'package:autonomy_flutter/service/metric_client_service.dart';
import 'package:autonomy_flutter/util/custom_exception.dart';
import 'package:autonomy_flutter/util/helpers.dart';
import 'package:autonomy_flutter/util/log.dart';
import 'package:autonomy_flutter/util/migration/migration_util.dart';
import 'package:floor/floor.dart';
@@ -23,6 +27,7 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';

class BackupService {
static const _dbFileName = 'cloud_database.db';
static const _dbEncryptedFileName = 'cloud_database.db.encrypted';

final IAPApi _iapApi;
@@ -40,11 +45,59 @@ class BackupService {
headers: {'requester': deviceId, 'Authorization': 'Bearer $authToken'});
}

Future<String> fetchBackupVersion(WalletStorage account) async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String version = packageInfo.version;

String? deviceId = await getBackupId();
final authToken = await getAuthToken(account);

final endpoint = Environment.autonomyAuthURL;

http.Response? response;

for (String filename in [_dbEncryptedFileName, _dbFileName]) {
try {
response = await http.get(
Uri.parse(
'$endpoint/apis/v1/premium/profile-data/versions?filename=$filename'),
headers: {
'requester': deviceId,
'Authorization': 'Bearer $authToken'
});
if (response.statusCode == 200) {
break;
}
} catch (e) {
log.warning('[BackupService] failed fetch $filename $e');
}
}

if (response == null || response.statusCode != 200) {
log.warning('[BackupService] failed fetchBackupVersion');
throw FailedFetchBackupVersion();
}

final result = BackupVersions.fromJson(json.decode(response.body));

var versions = result.versions..sort((a, b) => compareVersion(b, a));

String backupVersion = '';
for (String element in versions) {
if (compareVersion(element, version) <= 0) {
backupVersion = element;
break;
}
}

return backupVersion;
}

Future<bool> restoreCloudDatabaseIfNeed(WalletStorage account, String version,
{String dbName = 'cloud_database.db'}) async {
log.info('[BackupService] start database restore');
final isDatabaseExistOnFirestore = await _cloudFirestoreService.isExist();
if (!isDatabaseExistOnFirestore && false) {
if (isDatabaseExistOnFirestore) {
log.info('[BackupService] database not exist on firestore');
return false;
}
37 changes: 30 additions & 7 deletions lib/service/cloud_firestore_service.dart
Original file line number Diff line number Diff line change
@@ -27,8 +27,9 @@ class CloudFirestoreService {
return '${deviceId}_${packageInfo.packageName}';
}

CollectionReference getCollection(String collectionName) => fireBaseFirestore
.collection('$deviceId/$virtualDocumentId/$collectionName');
CollectionReference getCollection(FirestoreCollection collection) =>
fireBaseFirestore
.collection('$deviceId/$virtualDocumentId/${collection.name}');

// method getBatch
WriteBatch getBatch() => fireBaseFirestore.batch();
@@ -55,11 +56,10 @@ class CloudFirestoreService {
log.info('[BackupService] done database backup');
}

Future<bool> isExist() {
final collection =
fireBaseFirestore.collection('$deviceId/$virtualDocumentId');
return collection.get().then((value) => value.docs.isNotEmpty);
}
Future<bool> isExist() => getCollection(FirestoreCollection.persona)
.limit(1)
.get()
.then((value) => value.docs.isNotEmpty);

Future<void> copyFromSqliteDatabase(
SqliteCloudDatabase sqliteCloudDatabase) async {
@@ -75,3 +75,26 @@ class CloudFirestoreService {
await cloudFirestoreDatabase.addressDao.insertAddresses(addresses);
}
}

enum FirestoreCollection {
persona,
connection,
audit,
walletAddress,
settingsData;

String get name {
switch (this) {
case FirestoreCollection.persona:
return 'personas';
case FirestoreCollection.connection:
return 'connections';
case FirestoreCollection.audit:
return 'audit';
case FirestoreCollection.walletAddress:
return 'wallet_address';
case FirestoreCollection.settingsData:
return 'settings_data';
}
}
}
5 changes: 3 additions & 2 deletions lib/service/settings_data_service.dart
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@ class SettingsDataServiceImpl implements SettingsDataService {
final IAPApi _iapApi;
final CloudDatabase _cloudDB;
final CloudFirestoreService _cloudFirestoreService;
final _collection = FirestoreCollection.settingsData;

var latestDataHash = '';

@@ -122,7 +123,7 @@ class SettingsDataServiceImpl implements SettingsDataService {
Future firestoreBackup() async {
final data = await _getSettingsDataBackup();
final collection = _cloudFirestoreService
.getCollection('settings_data')
.getCollection(_collection)
.withConverter<SettingsDataBackup>(
fromFirestore: (snapshot, _) =>
SettingsDataBackup.fromJson(snapshot.data()!),
@@ -160,7 +161,7 @@ class SettingsDataServiceImpl implements SettingsDataService {
@override
Future restoreSettingsDataFromFirestore() {
final collection = _cloudFirestoreService
.getCollection('settings_data')
.getCollection(_collection)
.withConverter<SettingsDataBackup>(
fromFirestore: (snapshot, _) =>
SettingsDataBackup.fromJson(snapshot.data()!),
Loading