From 6476d7bf8ce4940d28c8c82118eeba9eb05aa2cc Mon Sep 17 00:00:00 2001 From: lifegpc Date: Fri, 2 Feb 2024 16:09:43 +0800 Subject: [PATCH] Check token info and update to new info --- ios/Podfile.lock | 8 +++++- ios/Runner/AppDelegate.swift | 13 +++++++++ lib/auth.dart | 41 ++++++++++++++++++++++++++++ lib/login.dart | 11 +------- lib/platform/device.dart | 9 ++++++ lib/platform/device_other.dart | 17 +++++++++++- lib/platform/device_web.dart | 4 +-- linux/my_application.cc | 21 ++++++++++++++ macos/Runner/MainFlutterWindow.swift | 12 ++++++++ windows/runner/flutter_window.cpp | 19 +++++++++++++ 10 files changed, 141 insertions(+), 14 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e8ee2b2..6a7c4df 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -6,6 +6,8 @@ PODS: - Flutter (1.0.0) - irondash_engine_context (0.0.1): - Flutter + - package_info_plus (0.4.5): + - Flutter - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS @@ -20,6 +22,7 @@ DEPENDENCIES: - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - Flutter (from `Flutter`) - irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`) @@ -33,6 +36,8 @@ EXTERNAL SOURCES: :path: Flutter irondash_engine_context: :path: ".symlinks/plugins/irondash_engine_context/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" shared_preferences_foundation: @@ -45,10 +50,11 @@ SPEC CHECKSUMS: device_info_plus: 7545d84d8d1b896cb16a4ff98c19f07ec4b298ea Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9 + package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 super_native_extensions: 4916b3c627a9c7fffdc48a23a9eca0b1ac228fa7 PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 -COCOAPODS: 1.14.2 +COCOAPODS: 1.15.0 diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index ed6364f..4615b75 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -207,6 +207,19 @@ class FilePickerDelegate: NSObject, UIDocumentPickerDelegate { result(FlutterMethodNotImplemented) } } + + let deviceChannel = FlutterMethodChannel( + name: "lifegpc.eh_downloader_flutter/device", + binaryMessenger: controller.binaryMessenger + ) + deviceChannel.setMethodCallHandler { (call, result) in + switch call.method { + case "deviceName": + result(UIDevice.current.name) + default: + result(FlutterMethodNotImplemented) + } + } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/auth.dart b/lib/auth.dart index 668cc81..300de91 100644 --- a/lib/auth.dart +++ b/lib/auth.dart @@ -1,7 +1,9 @@ import 'package:logging/logging.dart'; import 'api/status.dart'; +import 'api/token.dart'; import 'api/user.dart'; import 'globals.dart'; +import 'platform/device.dart'; final _log = Logger("AuthInfo"); @@ -11,6 +13,8 @@ class AuthInfo { BUser? get user => _user; ServerStatus? _status; ServerStatus? get status => _status; + Token? _token; + Token? get token => _token; bool get isAuthed => (_user != null); bool _checked = false; bool get checked => _checked; @@ -29,6 +33,42 @@ class AuthInfo { _status = (await api.getStatus()).unwrap(); } + Future checkSessionInfo() async { + final data = (await api.getToken()).unwrap(); + _token = data.token; + final d = await device; + final cv = await clientVersion; + final cp = clientPlatform; + String? client; + String? ed; + String? ecv; + String? ecp; + if (_token!.client != "flutter") { + client = "flutter"; + } + if (_token!.device != d) { + ed = d; + } + if (_token!.clientVersion != cv) { + ecv = cv; + } + if (_token!.clientPlatform != cp) { + ecp = cp; + } + if (client != null || ed != null || ecv != null || ecp != null) { + try { + final re = await api.updateToken( + client: client, + device: ed, + clientVersion: ecv, + clientPlatform: ecp); + _token = re.unwrap(); + } catch (e) { + _log.warning("Failed to update token:", e); + } + } + } + Future checkAuth() async { _isChecking = true; try { @@ -46,6 +86,7 @@ class AuthInfo { } _checked = true; await getServerStatus(); + await checkSessionInfo(); return re.ok; } finally { _isChecking = false; diff --git a/lib/login.dart b/lib/login.dart index a2c60b4..17a406f 100644 --- a/lib/login.dart +++ b/lib/login.dart @@ -3,7 +3,6 @@ import 'package:flutter/scheduler.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart'; -import 'package:package_info_plus/package_info_plus.dart'; import 'globals.dart'; import 'platform/device.dart'; @@ -18,14 +17,6 @@ class LoginPage extends StatefulWidget { State createState() => _LoginPageState(); } -Future get clientVersion async { - try { - return (await PackageInfo.fromPlatform()).version; - } catch (_) { - return null; - } -} - Future login(String username, String password) async { String baseUrl = api.baseUrl!; final u = Uri.parse(baseUrl); @@ -37,7 +28,7 @@ Future login(String username, String password) async { httpOnly: true, secure: u.scheme == 'https', client: "flutter", - device: device, + device: await device, clientVersion: await clientVersion, clientPlatform: clientPlatform); if (re.ok) return true; diff --git a/lib/platform/device.dart b/lib/platform/device.dart index bf17b73..98b4854 100644 --- a/lib/platform/device.dart +++ b/lib/platform/device.dart @@ -1 +1,10 @@ export './device_other.dart' if (dart.library.html) './device_web.dart'; +import 'package:package_info_plus/package_info_plus.dart'; + +Future get clientVersion async { + try { + return (await PackageInfo.fromPlatform()).version; + } catch (_) { + return null; + } +} diff --git a/lib/platform/device_other.dart b/lib/platform/device_other.dart index 49409ea..8b91a1d 100644 --- a/lib/platform/device_other.dart +++ b/lib/platform/device_other.dart @@ -1,6 +1,21 @@ import 'dart:io'; +import 'package:flutter/services.dart'; +import 'package:logging/logging.dart'; -String? get device => null; +const _platform = MethodChannel("lifegpc.eh_downloader_flutter/device"); +final _log = Logger("platformDevice"); +String? _device; + +Future get device async { + if (_device == null) { + try { + _device = await _platform.invokeMethod("deviceName"); + } catch (e) { + _log.warning("Failed to get device:", e); + } + } + return _device; +} String? get clientPlatform { if (Platform.isAndroid) return "android"; diff --git a/lib/platform/device_web.dart b/lib/platform/device_web.dart index fb54513..5d33186 100644 --- a/lib/platform/device_web.dart +++ b/lib/platform/device_web.dart @@ -3,7 +3,7 @@ import 'package:ua_parser_js/ua_parser_js.dart'; final _uaParser = UAParser(); String? _device; -String? get device { +Future get device { if (_device == null) { final ua = _uaParser.getResult(); _device = ua.browser.name; @@ -11,7 +11,7 @@ String? get device { _device = "$_device ${ua.browser.version}"; } } - return _device; + return Future.value(_device); } String? get clientPlatform => "web"; diff --git a/linux/my_application.cc b/linux/my_application.cc index 568a1c7..bed238d 100644 --- a/linux/my_application.cc +++ b/linux/my_application.cc @@ -15,6 +15,7 @@ struct _MyApplication { char** dart_entrypoint_arguments; FlMethodChannel* path_channel; FlMethodChannel* saf_channel; + FlMethodChannel* device_channel; }; G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) @@ -186,6 +187,21 @@ static void on_saf_channel_call(FlMethodChannel* channel, FlMethodCall* method_c } } +static void on_device_channel_call(FlMethodChannel* channel, FlMethodCall* method_call, + gpointer user_data) { + const gchar* method = fl_method_call_get_name(method_call); + if (g_strcmp0(method, "deviceName") == 0) { + const gchar* name = g_get_host_name(); + if (name) { + fl_method_call_respond_success(method_call, fl_value_new_string(name), nullptr); + } else { + fl_method_call_respond_success(method_call, fl_value_new_null(), nullptr); + } + } else { + fl_method_call_respond_not_implemented(method_call, nullptr); + } +} + // Implements GApplication::activate. static void my_application_activate(GApplication* application) { MyApplication* self = MY_APPLICATION(application); @@ -239,6 +255,10 @@ static void my_application_activate(GApplication* application) { fl_engine_get_binary_messenger(fl_view_get_engine(view)), "lifegpc.eh_downloader_flutter/saf", FL_METHOD_CODEC(codec)); fl_method_channel_set_method_call_handler(self->saf_channel, on_saf_channel_call, self, nullptr); + self->device_channel = fl_method_channel_new( + fl_engine_get_binary_messenger(fl_view_get_engine(view)), "lifegpc.eh_downloader_flutter/device", + FL_METHOD_CODEC(codec)); + fl_method_channel_set_method_call_handler(self->device_channel, on_device_channel_call, self, nullptr); gtk_widget_grab_focus(GTK_WIDGET(view)); } @@ -268,6 +288,7 @@ static void my_application_dispose(GObject* object) { g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); g_clear_object(&self->path_channel); g_clear_object(&self->saf_channel); + g_clear_object(&self->device_channel); G_OBJECT_CLASS(my_application_parent_class)->dispose(object); } diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift index 737efab..d434f78 100644 --- a/macos/Runner/MainFlutterWindow.swift +++ b/macos/Runner/MainFlutterWindow.swift @@ -136,6 +136,18 @@ class MainFlutterWindow: NSWindow { result(FlutterMethodNotImplemented) } } + + let deviceChannel = FlutterMethodChannel( + name: "lifegpc.eh_downloader_flutter/device", + binaryMessenger: flutterViewController.engine.binaryMessenger) + deviceChannel.setMethodCallHandler { (call, result) in + switch call.method { + case "deviceName": + result(Host.current().localizedName) + default: + result(FlutterMethodNotImplemented) + } + } RegisterGeneratedPlugins(registry: flutterViewController) diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp index 740d932..f8c2c70 100644 --- a/windows/runner/flutter_window.cpp +++ b/windows/runner/flutter_window.cpp @@ -248,6 +248,25 @@ bool FlutterWindow::OnCreate() { result->NotImplemented(); } }); + flutter::MethodChannel<> device(flutter_controller_->engine()->messenger(), "lifegpc.eh_downloader_flutter/device", + &flutter::StandardMethodCodec::GetInstance()); + device.SetMethodCallHandler([&](const flutter::MethodCall<>& call, std::unique_ptr> result) { + if (call.method_name() == "deviceName") { + wchar_t name[MAX_COMPUTERNAME_LENGTH + 1]; + if (!GetComputerNameW(name, MAX_COMPUTERNAME_LENGTH)) { + result->Success(); + return; + } + std::string deviceName; + if (!wchar_util::wstr_to_str(deviceName, name, CP_UTF8)) { + result->Error("ERROR", "Failed to convert device name to UTF-8."); + return; + } + result->Success(deviceName); + } else { + result->NotImplemented(); + } + }); SetChildContent(flutter_controller_->view()->GetNativeWindow());