From f91509502aceb99af4099e2d2a29d10e58748c3e Mon Sep 17 00:00:00 2001 From: Benimautner Date: Sun, 11 Feb 2024 23:30:45 +0100 Subject: [PATCH] added background token refresh every 12 hours to avoid expiration pushed version tag --- lib/api/user_implementation.dart | 5 ++ lib/global.dart | 15 ++++- lib/main.dart | 27 ++++++++- lib/service/mocked_services.dart | 6 ++ lib/service/services.dart | 2 + pubspec.lock | 100 +++++++++++++++++-------------- pubspec.yaml | 2 +- 7 files changed, 107 insertions(+), 50 deletions(-) diff --git a/lib/api/user_implementation.dart b/lib/api/user_implementation.dart index 50c9606..e9bcd7d 100644 --- a/lib/api/user_implementation.dart +++ b/lib/api/user_implementation.dart @@ -52,4 +52,9 @@ class UserAPIService extends APIService implements UserService { return userSettings; }); } + + @override + Future getToken() { + return client.post('/user/token').then((value) => value?.body["token"]); + } } diff --git a/lib/global.dart b/lib/global.dart index a9f68ec..5cf490c 100644 --- a/lib/global.dart +++ b/lib/global.dart @@ -94,13 +94,17 @@ class VikunjaGlobalState extends State { void updateWorkmanagerDuration() { Workmanager().cancelAll().then((value) { - settingsManager.getWorkmanagerDuration().then((duration) => + settingsManager.getWorkmanagerDuration().then((duration) { if(duration.inMinutes > 0) { Workmanager().registerPeriodicTask( "update-tasks", "update-tasks", frequency: duration, constraints: Constraints(networkType: NetworkType.connected), - initialDelay: Duration(seconds: 15), inputData: {"client_token": client.token, "client_base": client.base}) + initialDelay: Duration(seconds: 15), inputData: {"client_token": client.token, "client_base": client.base}); } + + Workmanager().registerPeriodicTask( + "refresh-token", "refresh-token", frequency: Duration(hours: 12), constraints: Constraints(networkType: NetworkType.connected), + initialDelay: Duration(seconds: 15)); }); }); } @@ -185,6 +189,13 @@ class VikunjaGlobalState extends State { User loadedCurrentUser; try { loadedCurrentUser = await UserAPIService(client).getCurrentUser(); + // load new token from server to avoid expiration + String? newToken = await newUserService?.getToken(); + if(newToken != null) { + _storage.write(key: currentUser, value: newToken); + client.configure(token: newToken); + } + } on ApiException catch (e) { dev.log("Error code: " + e.errorCode.toString(),level: 1000); if (e.errorCode ~/ 100 == 4) { diff --git a/lib/main.dart b/lib/main.dart index 40e3be0..b0ae919 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,6 +15,7 @@ import 'package:vikunja_app/theme/theme.dart'; import 'package:timezone/data/latest_all.dart' as tz; import 'package:flutter_downloader/flutter_downloader.dart'; +import 'api/user_implementation.dart'; import 'managers/notifications.dart'; class IgnoreCertHttpOverrides extends HttpOverrides { @@ -33,7 +34,7 @@ class IgnoreCertHttpOverrides extends HttpOverrides { @pragma('vm:entry-point') void callbackDispatcher() { - Workmanager().executeTask((task, inputData) { + Workmanager().executeTask((task, inputData) async { print("Native called background task: $task"); //simpleTask will be emitted here. if (task == "update-tasks" && inputData != null) { Client client = Client(null, @@ -55,6 +56,30 @@ void callbackDispatcher() { .scheduleDueNotifications(taskService) .then((value) => Future.value(true)); }); + } else if( task == "refresh-token") { + print("running refresh from workmanager"); + final FlutterSecureStorage _storage = new FlutterSecureStorage(); + + var currentUser = await _storage.read(key: 'currentUser'); + if (currentUser == null) { + return Future.value(true); + } + var token = await _storage.read(key: currentUser); + + + var base = await _storage.read(key: '${currentUser}_base'); + if (token == null || base == null) { + return Future.value(true); + } + Client client = Client(null); + client.configure(token: token, base: base, authenticated: true); + // load new token from server to avoid expiration + String? newToken = await UserAPIService(client).getToken(); + if(newToken != null) { + _storage.write(key: currentUser, value: newToken); + } + return Future.value(true); + } else { return Future.value(true); } diff --git a/lib/service/mocked_services.dart b/lib/service/mocked_services.dart index 6a55818..c63a262 100644 --- a/lib/service/mocked_services.dart +++ b/lib/service/mocked_services.dart @@ -218,5 +218,11 @@ class MockedUserService implements UserService { throw UnimplementedError(); } + @override + Future getToken() { + // TODO: implement getToken + throw UnimplementedError(); + } + } diff --git a/lib/service/services.dart b/lib/service/services.dart index 6467622..8582b3b 100644 --- a/lib/service/services.dart +++ b/lib/service/services.dart @@ -236,6 +236,8 @@ abstract class UserService { Future getCurrentUser(); Future setCurrentUserSettings(UserSettings userSettings); + + Future getToken(); } abstract class LabelService { diff --git a/pubspec.lock b/pubspec.lock index 3bd06a0..d91d67a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -257,6 +257,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -452,18 +460,18 @@ packages: dependency: "direct main" description: name: flutter_widget_from_html - sha256: d2ad036fb34a4f6ab84c21196788a5b1620f34d7930d16b32daadb511be24bb2 + sha256: "22c911b6ccf82b83e0c457d987bac4e703440fea0fc88dab24f4dfe995a5f33f" url: "https://pub.dev" source: hosted - version: "0.14.10+1" + version: "0.14.11" flutter_widget_from_html_core: dependency: transitive description: name: flutter_widget_from_html_core - sha256: "0e281196f962fd951da5b9d3fa50e0674fabf8fda92eafd8745d050d70877c68" + sha256: "028f4989b9ff4907466af233d50146d807772600d98a3e895662fbdb09c39225" url: "https://pub.dev" source: hosted - version: "0.14.10+1" + version: "0.14.11" frontend_server_client: dependency: transitive description: @@ -668,10 +676,10 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" nested: dependency: transitive description: @@ -748,10 +756,10 @@ packages: dependency: transitive description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: @@ -764,10 +772,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -780,10 +788,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -868,10 +876,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" pool: dependency: transitive description: @@ -1009,18 +1017,18 @@ packages: dependency: transitive description: name: sqflite - sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" + sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6 url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.2" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 + sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5" url: "https://pub.dev" source: hosted - version: "2.5.0+2" + version: "2.5.3" stack_trace: dependency: transitive description: @@ -1105,26 +1113,26 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86 + sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.2.4" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: c0766a55ab42cefaa728cabc951e82919ab41a3a4fee0aaa96176ca82da8cc51 + sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.2" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "46b81e3109cbb2d6b81702ad3077540789a3e74e22795eb9f0b7d494dbaa72ea" + sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.2.4" url_launcher_linux: dependency: transitive description: @@ -1145,10 +1153,10 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: "4aca1e060978e19b2998ee28503f40b5ba6226819c2b5e3e4d1821e8ccd92198" + sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" url_launcher_web: dependency: transitive description: @@ -1169,34 +1177,34 @@ packages: dependency: transitive description: name: uuid - sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f" + sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 url: "https://pub.dev" source: hosted - version: "4.2.2" + version: "4.3.3" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43" + sha256: "4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752" url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.10+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7" + sha256: f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33 url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.10+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26 + sha256: "18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a" url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.10+1" vector_math: dependency: transitive description: @@ -1225,18 +1233,18 @@ packages: dependency: transitive description: name: video_player_avfoundation - sha256: "752b783a00748684312dd6a68e22f795281d295921e69ae5ad36f90b7fb39cdb" + sha256: "309e3962795e761be010869bae65c0b0e45b5230c5cee1bec72197ca7db040ed" url: "https://pub.dev" source: hosted - version: "2.5.5" + version: "2.5.6" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a + sha256: "236454725fafcacf98f0f39af0d7c7ab2ce84762e3b63f2cbb3ef9a7e0550bc6" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.2" video_player_web: dependency: transitive description: @@ -1329,34 +1337,34 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: "60e23976834e995c404c0b21d3b9db37ecd77d3303ef74f8b8d7a7b19947fc04" + sha256: d81b68e88cc353e546afb93fb38958e3717282c5ac6e5d3be4a4aef9fc3c1413 url: "https://pub.dev" source: hosted - version: "4.4.3" + version: "4.5.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "161af93c2abaf94ef2192bffb53a3658b2d721a3bf99b69aa1e47814ee18cc96" + sha256: "3e5f4e9d818086b0d01a66fb1ff9cc72ab0cc58c71980e3d3661c5685ea0efb0" url: "https://pub.dev" source: hosted - version: "3.13.2" + version: "3.15.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: dbe745ee459a16b6fec296f7565a8ef430d0d681001d8ae521898b9361854943 + sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "02d8f3ebbc842704b2b662377b3ee11c0f8f1bbaa8eab6398262f40049819160" + sha256: "4d062ad505390ecef1c4bfb6001cd857a51e00912cc9dfb66edb1886a9ebd80c" url: "https://pub.dev" source: hosted - version: "3.10.1" + version: "3.10.2" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 675900c..7961165 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: vikunja_app description: Vikunja as Flutter cross platform app -version: 0.1.3-beta +version: 0.1.4-beta environment: sdk: ">=2.18.0 <3.0.0"