Skip to content

Commit

Permalink
auto refresh session before expiring
Browse files Browse the repository at this point in the history
updated package_info_plus
  • Loading branch information
oliverbytes committed Oct 21, 2022
1 parent 9609aff commit d95b445
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 127 deletions.
216 changes: 109 additions & 107 deletions lib/features/files/sync.service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,6 @@ class SyncService extends GetxService with ConsoleMixin {

// FUNCTIONS

Future<Either<dynamic, bool>> purge() async {
if (!isReady) return const Left('offline');
final result = await SupabaseFunctionsService.to.deleteDirectory('');
if (result.isLeft) return Left(result.left);
return const Right(true);
}

Future<Either<dynamic, bool>> sync() async {
if (!isReady) return const Right(false);

Expand Down Expand Up @@ -100,6 +93,8 @@ class SyncService extends GetxService with ConsoleMixin {
onTimeout: () => const Left('Timed Out'),
);

// stop syncing indicator
syncing.value = false;
if (downResult.isLeft) return Left(downResult.left);
// we are now ready to upSync because we are not in sync with server
inSync.value = true;
Expand All @@ -110,7 +105,6 @@ class SyncService extends GetxService with ConsoleMixin {
onTimeout: () => const Left('Timed Out'),
);

syncing.value = false;
// reload all list
MainScreenController.to.load();

Expand Down Expand Up @@ -141,104 +135,6 @@ class SyncService extends GetxService with ConsoleMixin {
return const Right(true);
}

Future<void> _mergeGroups(LisoVault vault) async {
final server = vault.groups;
final local = GroupsService.to.box!;
console
.wtf('merged groups local: ${local.length}, server: ${server.length}');

// merge server and local items
final merged = [...server, ...local.values];
// TODO: temporarily remove previously added groups
merged.removeWhere((e) => e.isReserved);
// sort all from most to least updated time
merged.sort(
(a, b) => b.metadata!.updatedTime.compareTo(a.metadata!.updatedTime),
);

// exclude permanently flagged deleted items
final deletedIds =
"${Persistence.to.deletedGroupIds},${vault.persistence['deleted-group-ids']}";
merged.removeWhere((e) => deletedIds.contains(e.id));

// leave only the most updated items
final newList = <HiveLisoGroup>[];

for (final item in merged) {
final exists = newList.where((e) => e.id == item.id).isNotEmpty;
if (exists) continue;
newList.addIf(!newList.contains(item), item);
}

console.wtf('merged groups: ${newList.length}');
await local.clear();
await local.addAll(newList);
}

Future<void> _mergeCategories(LisoVault vault) async {
final server = vault.categories ?? [];
final local = CategoriesService.to.box!;
console.wtf(
'merged categories local: ${local.length}, server: ${server.length}');
// merge server and local items
final merged = [...server, ...local.values];
// sort all from most to least updated time
merged.sort(
(a, b) => b.metadata!.updatedTime.compareTo(a.metadata!.updatedTime),
);

// exclude permanently flagged deleted items
final deletedIds =
"${Persistence.to.deletedCategoryIds},${vault.persistence['deleted-category-ids']}";
merged.removeWhere((e) => deletedIds.contains(e.id));

// leave only the most updated items
final newList = <HiveLisoCategory>[];

for (final item in merged) {
final exists = newList.where((e) => e.id == item.id).isNotEmpty;
if (exists) continue;
newList.addIf(!newList.contains(item), item);
}

console.wtf('merged categories: ${newList.length}');
await local.clear();
await local.addAll(newList);
}

Future<void> _mergeItems(LisoVault vault) async {
final server = vault.items;
final local = ItemsService.to.box!;
console.wtf(
'merged items local: ${local.length}, server: ${server.length}',
);

// merge server and local items
final merged = [...server, ...local.values];
// sort all from most to least updated time
merged.sort(
(a, b) => b.metadata.updatedTime.compareTo(a.metadata.updatedTime),
);

// exclude permanently flagged deleted items
final deletedIds =
"${Persistence.to.deletedItemIds},${vault.persistence['deleted-item-ids']}";
merged.removeWhere((e) => deletedIds.contains(e.identifier));
// leave only the most updated items
final newList = <HiveLisoItem>[];

for (final item in merged) {
final exists =
newList.where((e) => e.identifier == item.identifier).isNotEmpty;
if (exists) continue;
newList.addIf(!newList.contains(item), item);
}

console.wtf('merged items: ${newList.length}');
await local.clear();
await local.addAll(newList);
}

Future<void> backup(String object, Uint8List encryptedBytes) async {
if (!isReady) return console.warning('offline');
if (backedUp) {
Expand All @@ -263,7 +159,6 @@ class SyncService extends GetxService with ConsoleMixin {
}

// DO THE ACTUAL BACKUP

final presignResult = await SupabaseFunctionsService.to.presignUrl(
object:
'$kDirBackups/${DateTime.now().millisecondsSinceEpoch}-$kVaultFileName',
Expand Down Expand Up @@ -385,4 +280,111 @@ class SyncService extends GetxService with ConsoleMixin {
console.wtf('done');
return const Right(true);
}

Future<Either<dynamic, bool>> purge() async {
if (!isReady) return const Left('offline');
final result = await SupabaseFunctionsService.to.deleteDirectory('');
if (result.isLeft) return Left(result.left);
return const Right(true);
}

// MERGING

Future<void> _mergeGroups(LisoVault vault) async {
final server = vault.groups;
final local = GroupsService.to.box!;
console
.wtf('merged groups local: ${local.length}, server: ${server.length}');

// merge server and local items
final merged = [...server, ...local.values];
// TODO: temporarily remove previously added groups
merged.removeWhere((e) => e.isReserved);
// sort all from most to least updated time
merged.sort(
(a, b) => b.metadata!.updatedTime.compareTo(a.metadata!.updatedTime),
);

// exclude permanently flagged deleted items
final deletedIds =
"${Persistence.to.deletedGroupIds},${vault.persistence['deleted-group-ids']}";
merged.removeWhere((e) => deletedIds.contains(e.id));

// leave only the most updated items
final newList = <HiveLisoGroup>[];

for (final item in merged) {
final exists = newList.where((e) => e.id == item.id).isNotEmpty;
if (exists) continue;
newList.addIf(!newList.contains(item), item);
}

console.wtf('merged groups: ${newList.length}');
await local.clear();
await local.addAll(newList);
}

Future<void> _mergeCategories(LisoVault vault) async {
final server = vault.categories ?? [];
final local = CategoriesService.to.box!;
console.wtf(
'merged categories local: ${local.length}, server: ${server.length}');
// merge server and local items
final merged = [...server, ...local.values];
// sort all from most to least updated time
merged.sort(
(a, b) => b.metadata!.updatedTime.compareTo(a.metadata!.updatedTime),
);

// exclude permanently flagged deleted items
final deletedIds =
"${Persistence.to.deletedCategoryIds},${vault.persistence['deleted-category-ids']}";
merged.removeWhere((e) => deletedIds.contains(e.id));

// leave only the most updated items
final newList = <HiveLisoCategory>[];

for (final item in merged) {
final exists = newList.where((e) => e.id == item.id).isNotEmpty;
if (exists) continue;
newList.addIf(!newList.contains(item), item);
}

console.wtf('merged categories: ${newList.length}');
await local.clear();
await local.addAll(newList);
}

Future<void> _mergeItems(LisoVault vault) async {
final server = vault.items;
final local = ItemsService.to.box!;
console.wtf(
'merged items local: ${local.length}, server: ${server.length}',
);

// merge server and local items
final merged = [...server, ...local.values];
// sort all from most to least updated time
merged.sort(
(a, b) => b.metadata.updatedTime.compareTo(a.metadata.updatedTime),
);

// exclude permanently flagged deleted items
final deletedIds =
"${Persistence.to.deletedItemIds},${vault.persistence['deleted-item-ids']}";
merged.removeWhere((e) => deletedIds.contains(e.identifier));
// leave only the most updated items
final newList = <HiveLisoItem>[];

for (final item in merged) {
final exists =
newList.where((e) => e.identifier == item.identifier).isNotEmpty;
if (exists) continue;
newList.addIf(!newList.contains(item), item);
}

console.wtf('merged items: ${newList.length}');
await local.clear();
await local.addAll(newList);
}
}
37 changes: 23 additions & 14 deletions lib/features/supabase/supabase_auth.service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,13 @@ class SupabaseAuthService extends GetxService with ConsoleMixin {
);

initAuthState();
var sessionString = persistence.supabaseSession.val;
if (sessionString.isEmpty) return console.warning('no supabase session');

try {
final session = await client!.auth.recoverSession(sessionString);
console.info('recovered session! user id: ${session.user?.id}');
} on AuthException catch (e) {
console.error('recover session error: $e');
} catch (e, s) {
CrashlyticsService.to.record(e, s);
console.error('recover session exception: $e');
}
recoverSession();
}

void initAuthState() {
client!.auth.onAuthStateChange.listen((data) {
console.info(
'onAuthStateChange! ${data.event}: user id: ${data.session?.user.id}',
'onAuthStateChange! ${data.event}: user id: ${data.session?.user.id}, expires at: ${DateTime.fromMillisecondsSinceEpoch(data.session!.expiresAt! * 1000)}',
);

persistence.supabaseSession.val =
Expand All @@ -73,9 +62,14 @@ class SupabaseAuthService extends GetxService with ConsoleMixin {

ProController.to.login(user!);
AnalyticsService.to.logSignIn();

// refresh token 2 minutes before expiration time
final refreshAfter = (data.session!.expiresIn! - 120);
Future.delayed(refreshAfter.seconds)
.then((value) => recoverSession());
});
} else if (data.event == AuthChangeEvent.signedOut) {
EasyDebounce.debounce('auth-sign-out', 1.seconds, () {
EasyDebounce.debounce('auth-sign-out', 5.seconds, () {
ProController.to.logout();
AnalyticsService.to.logSignOut();
});
Expand All @@ -87,6 +81,21 @@ class SupabaseAuthService extends GetxService with ConsoleMixin {
});
}

Future<void> recoverSession() async {
var sessionString = persistence.supabaseSession.val;
if (sessionString.isEmpty) return console.warning('no supabase session');

try {
final session = await client!.auth.recoverSession(sessionString);
console.info('recovered session! user id: ${session.user?.id}');
} on AuthException catch (e) {
console.error('recover session error: $e');
} catch (e, s) {
CrashlyticsService.to.record(e, s);
console.error('recover session exception: $e');
}
}

Future<void> signIn(String email, String password) async {
try {
await client!.auth.signInWithPassword(email: email, password: password);
Expand Down
2 changes: 1 addition & 1 deletion macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import firebase_analytics
import firebase_core
import firebase_crashlytics
import flutter_local_notifications
import package_info_plus_macos
import package_info_plus
import pasteboard
import path_provider_macos
import platform_device_id
Expand Down
10 changes: 5 additions & 5 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ dependencies:
blur: ^3.1.0 # blurring of seed phrases
flutter_json_viewer: ^1.0.1 #json viewer
flutter_swipe_action_cell: ^3.0.4
flutter_quill: ^6.0.9
flutter_quill: ^6.0.10
badges: ^2.0.3 # pending changes indicator
cached_network_image: ^3.2.2 # load remote images
percent_indicator: ^4.2.2 # circular progress indicator
Expand Down Expand Up @@ -107,11 +107,11 @@ dependencies:
# INFO
device_info_plus: ^7.0.1
platform_device_id: ^1.0.1
package_info_plus: ^1.4.3+1
connectivity_plus: ^3.0.1 # internet connectivity checking
package_info_plus: ^3.0.1
connectivity_plus: ^3.0.2 # internet connectivity checking

dependency_overrides:
device_info_plus: ^7.0.1
dependency_overrides:
package_info_plus: ^3.0.1

dev_dependencies:
# flutter_test:
Expand Down

0 comments on commit d95b445

Please sign in to comment.