diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 38ea1d8e..9e8e1365 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -470,7 +470,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -478,7 +478,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -602,7 +602,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -610,7 +610,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -628,7 +628,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -636,7 +636,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -657,7 +657,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -670,7 +670,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -696,7 +696,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -709,7 +709,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -732,7 +732,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -745,7 +745,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/lib/core/update.dart b/lib/core/update.dart index 96955a67..5733c8ae 100644 --- a/lib/core/update.dart +++ b/lib/core/update.dart @@ -6,6 +6,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:logging/logging.dart'; import 'package:r_upgrade/r_upgrade.dart'; import 'package:toolbox/core/extension/navigator.dart'; +import 'package:toolbox/core/utils/misc.dart' hide pathJoin; +import 'package:toolbox/data/model/app/update.dart'; import 'package:toolbox/data/res/path.dart'; import '../data/provider/app.dart'; @@ -16,6 +18,7 @@ import 'utils/platform.dart'; import 'utils/ui.dart'; final _logger = Logger('UPDATE'); +late final String _dlDir; Future isFileAvailable(String url) async { try { @@ -28,7 +31,7 @@ Future isFileAvailable(String url) async { } Future doUpdate(BuildContext context, {bool force = false}) async { - _rmDownloadApks(); + await _rmDownloadApks(); final update = await locator().getUpdate(); @@ -68,7 +71,7 @@ Future doUpdate(BuildContext context, {bool force = false}) async { child: Text(s.updateTipTooLow(newest)), actions: [ TextButton( - onPressed: () => _doUpdate(url, context, s), + onPressed: () => _doUpdate(update, context, s), child: Text(s.ok), ) ], @@ -80,17 +83,36 @@ Future doUpdate(BuildContext context, {bool force = false}) async { context, '${s.updateTip(newest)} \n${update.changelog.current}', s.update, - () => _doUpdate(url, context, s), + () => _doUpdate(update, context, s), ); } -Future _doUpdate(String url, BuildContext context, S s) async { +Future _doUpdate(AppUpdate update, BuildContext context, S s) async { if (isAndroid) { - await RUpgrade.upgrade( + final url = update.url.current; + if (url == null) return; + final fileName = url.split('/').last; + final id = await RUpgrade.upgrade( url, - fileName: url.split('/').last, - isAutoRequestInstall: true, + fileName: fileName, + isAutoRequestInstall: false, ); + if (id == null) { + showSnackBar(context, const Text('install id is null')); + return; + } + final sha256 = update.sha256.current; + if (sha256 == null) { + showSnackBar(context, const Text('sha256 is null')); + return; + } + final dlPath = pathJoin(_dlDir, fileName); + final computed = await getFileSha256(dlPath); + if (computed != sha256) { + showSnackBar(context, Text('Mismatch sha256: $computed, $sha256')); + return; + } + RUpgrade.install(id); } else if (isIOS) { await RUpgrade.upgradeFromAppStore('1586449703'); } else { @@ -110,7 +132,8 @@ Future _doUpdate(String url, BuildContext context, S s) async { // rmdir Download Future _rmDownloadApks() async { if (!isAndroid) return; - final dlDir = Directory(pathJoin((await docDir).path, 'Download')); + _dlDir = pathJoin((await docDir).path, 'Download'); + final dlDir = Directory(_dlDir); if (await dlDir.exists()) { await dlDir.delete(recursive: true); } diff --git a/lib/core/utils/misc.dart b/lib/core/utils/misc.dart index 3784eebb..384e63ee 100644 --- a/lib/core/utils/misc.dart +++ b/lib/core/utils/misc.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:crypto/crypto.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; @@ -77,3 +78,12 @@ String getTime(int? unixMill) { String pathJoin(String path1, String path2) { return path1 + (path1.endsWith('/') ? '' : '/') + path2; } + +Future getFileSha256(String path) async { + final file = File(path); + if (!(await file.exists())) { + return null; + } + final digest = await sha256.bind(file.openRead()).first; + return digest.toString(); +} diff --git a/lib/data/model/app/shell_func.dart b/lib/data/model/app/shell_func.dart index 46b40fe7..bf920d27 100644 --- a/lib/data/model/app/shell_func.dart +++ b/lib/data/model/app/shell_func.dart @@ -75,12 +75,14 @@ esac'''); } } -abstract class _CmdType { +extension EnumX on Enum { /// Find out the required segment from [segments] - String find(List segments); + String find(List segments) { + return segments[index]; + } } -enum StatusCmdType implements _CmdType { +enum StatusCmdType { net, sys, cpu, @@ -92,21 +94,11 @@ enum StatusCmdType implements _CmdType { tempVal, host, sysRhel; - - @override - String find(List segments) { - return segments[index]; - } } -enum DockerCmdType implements _CmdType { +enum DockerCmdType { version, ps, stats, images; - - @override - String find(List segments) { - return segments[index]; - } } diff --git a/lib/data/model/app/update.dart b/lib/data/model/app/update.dart index 01a8d592..f087a92a 100644 --- a/lib/data/model/app/update.dart +++ b/lib/data/model/app/update.dart @@ -34,11 +34,13 @@ class AppUpdate { required this.changelog, required this.build, required this.url, + required this.sha256, }); final AppUpdatePlatformSpecific changelog; final Build build; final AppUpdatePlatformSpecific url; + final AppUpdatePlatformSpecific sha256; factory AppUpdate.fromRawJson(String str) => AppUpdate.fromJson(json.decode(str)); @@ -49,12 +51,14 @@ class AppUpdate { changelog: AppUpdatePlatformSpecific.fromJson(json["changelog"]), build: Build.fromJson(json["build"]), url: AppUpdatePlatformSpecific.fromJson(json["url"]), + sha256: AppUpdatePlatformSpecific.fromJson(json["sha256"]), ); Map toJson() => { "changelog": changelog.toJson(), "build": build.toJson(), "url": url.toJson(), + "sha256": sha256.toJson(), }; } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 0e3ceca5..84db99be 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,8 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 451; + static const int build = 452; static const String engine = "3.10.6"; - static const String buildAt = "2023-08-08 15:07:48.571249"; - static const int modifications = 3; + static const String buildAt = "2023-08-08 16:29:00.513310"; + static const int modifications = 11; } diff --git a/lib/data/res/server_cmd.dart b/lib/data/res/server_cmd.dart index 47c319ad..952ef8ad 100644 --- a/lib/data/res/server_cmd.dart +++ b/lib/data/res/server_cmd.dart @@ -32,7 +32,7 @@ final shellCmd = """ # Script for app `${BuildData.name} v1.0.${BuildData.build}` # Delete this file while app is running will cause app crash -export LANG=en_US.utf-8 +export LANG="en_US.UTF-8" ${AppShellFuncType.shellScript} """; diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index ed866e6a..afb0fb84 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -479,7 +479,9 @@ class _ServerPageState extends State final file = File(path); final shouldGenKey = spi.pubKeyId != null; if (shouldGenKey) { - await file.delete(); + if (await file.exists()) { + await file.delete(); + } await file.writeAsString(getPrivateKey(spi.pubKeyId!)); extraArgs.addAll(["-i", path]); } diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 1998a121..d00a0ba6 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -475,9 +475,9 @@ baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -490,9 +490,9 @@ baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -505,9 +505,9 @@ baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 451; + CURRENT_PROJECT_VERSION = 452; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.451; + MARKETING_VERSION = 1.0.452; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/make.dart b/make.dart index 040b5456..94203414 100755 --- a/make.dart +++ b/make.dart @@ -146,7 +146,7 @@ Future scp2CDN() async { print('SHA1: $sha1'); final result = await Process.run( 'scp', - [apkPath, 'hk:/var/www/res/serverbox/apks/$build-$sha1.apk'], + [apkPath, 'hk:/var/www/res/serverbox/apks/$build.apk'], runInShell: true, ); if (result.exitCode != 0) { diff --git a/pubspec.lock b/pubspec.lock index fbe35f69..b3c29148 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -211,7 +211,7 @@ packages: source: hosted version: "0.3.3+4" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab diff --git a/pubspec.yaml b/pubspec.yaml index 877d3655..5abf48d0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -66,6 +66,7 @@ dependencies: code_text_field: ^1.1.0 nil: ^1.1.1 shared_preferences: ^2.1.1 + crypto: ^3.0.3 dev_dependencies: flutter_native_splash: ^2.1.6