feat: keyboard-interactive auth (#349)

This commit is contained in:
lollipopkit
2024-05-07 15:22:31 +08:00
parent 026e414388
commit d0523c1e54
15 changed files with 137 additions and 69 deletions

View File

@@ -690,7 +690,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -700,7 +700,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -826,7 +826,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -836,7 +836,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -854,7 +854,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -864,7 +864,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -885,7 +885,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -898,7 +898,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
@@ -924,7 +924,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -937,7 +937,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -960,7 +960,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -973,7 +973,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -996,7 +996,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -1008,7 +1008,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
@@ -1037,7 +1037,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -1049,7 +1049,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;
@@ -1075,7 +1075,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -1087,7 +1087,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;

View File

@@ -61,13 +61,16 @@ extension DialogX on BuildContext {
static final _recoredPwd = <String, String>{}; static final _recoredPwd = <String, String>{};
/// Show a dialog to input password
///
/// [hostId] set it to null to skip remembering the password
Future<String?> showPwdDialog({ Future<String?> showPwdDialog({
String? user, String? hostId,
required String hostId, String? title,
}) async { }) async {
if (!mounted) return null; if (!mounted) return null;
return await showRoundDialog<String>( return await showRoundDialog<String>(
title: Text(user ?? l10n.pwd), title: Text(title ?? hostId ?? l10n.pwd),
child: Input( child: Input(
controller: TextEditingController(text: _recoredPwd[hostId]), controller: TextEditingController(text: _recoredPwd[hostId]),
autoFocus: true, autoFocus: true,
@@ -75,7 +78,7 @@ extension DialogX on BuildContext {
obscureText: true, obscureText: true,
onSubmitted: (val) { onSubmitted: (val) {
pop(val); pop(val);
if (Stores.setting.rememberPwdInMem.fetch()) { if (hostId != null && Stores.setting.rememberPwdInMem.fetch()) {
_recoredPwd[hostId] = val; _recoredPwd[hostId] = val;
} }
}, },

View File

@@ -81,9 +81,9 @@ extension SSHClientX on SSHClient {
isRequestingPwd = true; isRequestingPwd = true;
final user = Miscs.pwdRequestWithUserReg.firstMatch(data)?.group(1); final user = Miscs.pwdRequestWithUserReg.firstMatch(data)?.group(1);
if (context == null) return; if (context == null) return;
final pwd = await context.showPwdDialog(user: user, hostId: id); final pwd = await context.showPwdDialog(title: user, hostId: id);
if (pwd == null || pwd.isEmpty) { if (pwd == null || pwd.isEmpty) {
session.kill(SSHSignal.INT); session.kill(SSHSignal.TERM);
} else { } else {
session.stdin.add('$pwd\n'.uint8List); session.stdin.add('$pwd\n'.uint8List);
} }

20
lib/core/utils/auth.dart Normal file
View File

@@ -0,0 +1,20 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/data/model/server/server_private_info.dart';
import 'package:toolbox/data/res/provider.dart';
abstract final class KeybordInteractive {
static FutureOr<List<String>?> defaultHandle(
ServerPrivateInfo spi, {
BuildContext? ctx,
}) async {
try {
final res = await (ctx ?? Pros.app.ctx)?.showPwdDialog(title: spi.id);
return res == null ? null : [res];
} catch (e) {
return null;
}
}
}

View File

@@ -56,6 +56,9 @@ Future<SSHClient> genClient(
/// ///
/// Must pass this param when use multi-thread and key login /// Must pass this param when use multi-thread and key login
ServerPrivateInfo? jumpSpi, ServerPrivateInfo? jumpSpi,
/// Handle keyboard-interactive authentication
FutureOr<List<String>?> Function(SSHUserInfoRequest)? onKeyboardInteractive,
}) async { }) async {
onStatus?.call(GenSSHClientStatus.socket); onStatus?.call(GenSSHClientStatus.socket);
@@ -109,6 +112,9 @@ Future<SSHClient> genClient(
socket, socket,
username: spi.user, username: spi.user,
onPasswordRequest: () => spi.pwd, onPasswordRequest: () => spi.pwd,
onUserInfoRequest: onKeyboardInteractive,
printDebug: debugPrint,
printTrace: debugPrint,
); );
} }
privateKey ??= getPrivateKey(keyId); privateKey ??= getPrivateKey(keyId);
@@ -119,5 +125,8 @@ Future<SSHClient> genClient(
username: spi.user, username: spi.user,
// Must use [compute] here, instead of [Computer.shared.start] // Must use [compute] here, instead of [Computer.shared.start]
identities: await compute(loadIndentity, privateKey), identities: await compute(loadIndentity, privateKey),
onUserInfoRequest: onKeyboardInteractive,
printDebug: debugPrint,
printTrace: debugPrint,
); );
} }

View File

@@ -9,4 +9,6 @@ class AppProvider extends ChangeNotifier {
} }
bool moveBg = true; bool moveBg = true;
BuildContext? ctx;
} }

View File

@@ -6,6 +6,7 @@ import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:toolbox/core/extension/ssh_client.dart';
import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/utils/auth.dart';
import 'package:toolbox/core/utils/platform/path.dart'; import 'package:toolbox/core/utils/platform/path.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/app/shell_func.dart';
import 'package:toolbox/data/model/server/system.dart'; import 'package:toolbox/data/model/server/system.dart';
@@ -278,15 +279,14 @@ class ServerProvider extends ChangeNotifier {
s.client = await genClient( s.client = await genClient(
spi, spi,
timeout: Duration(seconds: Stores.setting.timeout.fetch()), timeout: Duration(seconds: Stores.setting.timeout.fetch()),
onKeyboardInteractive: (_) => KeybordInteractive.defaultHandle(spi),
); );
final time2 = DateTime.now(); final time2 = DateTime.now();
final spentTime = time2.difference(time1).inMilliseconds; final spentTime = time2.difference(time1).inMilliseconds;
if (spi.jumpId == null) { if (spi.jumpId == null) {
Loggers.app.info('Connected to ${spi.name} in $spentTime ms.'); Loggers.app.info('Connected to ${spi.name} in $spentTime ms.');
} else { } else {
Loggers.app.info( Loggers.app.info('Jump to ${spi.name} in $spentTime ms.');
'Connected to ${spi.name} via jump server in $spentTime ms.',
);
} }
} catch (e) { } catch (e) {
TryLimiter.inc(sid); TryLimiter.inc(sid);
@@ -316,6 +316,11 @@ class ServerProvider extends ChangeNotifier {
s.status.err = e.toString(); s.status.err = e.toString();
_setServerState(s, ServerState.failed); _setServerState(s, ServerState.failed);
return; return;
} on SSHAuthFailError catch (e) {
TryLimiter.inc(sid);
s.status.err = e.toString();
_setServerState(s, ServerState.failed);
return;
} catch (e) { } catch (e) {
Loggers.app.warning('Write script to ${spi.name} by shell', e); Loggers.app.warning('Write script to ${spi.name} by shell', e);
@@ -351,6 +356,8 @@ class ServerProvider extends ChangeNotifier {
} }
} }
if (s.state == ServerState.connecting) return;
/// Keep [finished] state, or the UI will be refreshed to [loading] state /// Keep [finished] state, or the UI will be refreshed to [loading] state
/// instead of the '$Temp | $Uptime'. /// instead of the '$Temp | $Uptime'.
/// eg: '32C | 7 days' /// eg: '32C | 7 days'

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 876; static const int build = 877;
static const String engine = "3.19.6"; static const String engine = "3.19.6";
static const String buildAt = "2024-04-26 23:44:14"; static const String buildAt = "2024-05-07 15:17:19";
static const int modifications = 4; static const int modifications = 15;
static const int script = 45; static const int script = 45;
} }

View File

@@ -70,5 +70,6 @@ abstract final class GithubIds {
'zj1123581321', 'zj1123581321',
'pctoolsx', 'pctoolsx',
'pgs666', 'pgs666',
'FHU-yezi',
}; };
} }

View File

@@ -120,6 +120,7 @@ class _HomePageState extends State<HomePage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
Pros.app.ctx = context;
return Scaffold( return Scaffold(
drawer: _buildDrawer(), drawer: _buildDrawer(),

View File

@@ -16,6 +16,7 @@ import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/core/utils/share.dart'; import 'package:toolbox/core/utils/share.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/app/shell_func.dart';
import 'package:toolbox/data/model/server/try_limiter.dart'; import 'package:toolbox/data/model/server/try_limiter.dart';
import 'package:toolbox/data/res/color.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/provider.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/view/widget/percent_circle.dart'; import 'package:toolbox/view/widget/percent_circle.dart';
@@ -432,8 +433,48 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildServerCardTitle(Server s) { Widget _buildServerCardTitle(Server s) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 7),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ConstrainedBox(
constraints: BoxConstraints(maxWidth: _media.size.width / 2.3),
child: Text(
s.spi.name,
style: UIs.text13Bold,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
const Icon(
Icons.keyboard_arrow_right,
size: 17,
color: Colors.grey,
),
const Spacer(),
_buildTopRightText(s),
_buildTopRightWidget(s),
],
),
);
}
Widget _buildTopRightWidget(Server s) {
Widget rightCorner = UIs.placeholder; Widget rightCorner = UIs.placeholder;
if (s.state == ServerState.failed) { if (s.state == ServerState.connecting) {
rightCorner = Padding(
padding: const EdgeInsets.symmetric(horizontal: 7),
child: SizedBox(
width: 21,
height: 21,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(primaryColor),
),
),
);
} else if (s.state == ServerState.failed) {
rightCorner = InkWell( rightCorner = InkWell(
onTap: () { onTap: () {
TryLimiter.reset(s.spi.id); TryLimiter.reset(s.spi.id);
@@ -464,31 +505,7 @@ class _ServerPageState extends State<ServerPage>
} else if (Stores.setting.serverTabUseOldUI.fetch()) { } else if (Stores.setting.serverTabUseOldUI.fetch()) {
rightCorner = ServerFuncBtnsTopRight(spi: s.spi); rightCorner = ServerFuncBtnsTopRight(spi: s.spi);
} }
return Padding( return rightCorner;
padding: const EdgeInsets.symmetric(horizontal: 7),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ConstrainedBox(
constraints: BoxConstraints(maxWidth: _media.size.width / 2.3),
child: Text(
s.spi.name,
style: UIs.text13Bold,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
const Icon(
Icons.keyboard_arrow_right,
size: 17,
color: Colors.grey,
),
const Spacer(),
_buildTopRightText(s),
rightCorner,
],
),
);
} }
Widget _buildTopRightText(Server s) { Widget _buildTopRightText(Server s) {

View File

@@ -9,6 +9,7 @@ import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/utils/auth.dart';
import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/core/utils/server.dart'; import 'package:toolbox/core/utils/server.dart';
import 'package:toolbox/core/utils/share.dart'; import 'package:toolbox/core/utils/share.dart';
@@ -384,9 +385,16 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
Future<void> _initTerminal() async { Future<void> _initTerminal() async {
_writeLn('Connecting...\r\n'); _writeLn('Connecting...\r\n');
_client ??= await genClient(widget.spi); _client ??= await genClient(
_writeLn('Starting shell...\r\n'); widget.spi,
onStatus: (p0) {
_writeLn(p0.toString());
},
onKeyboardInteractive: (_) =>
KeybordInteractive.defaultHandle(widget.spi),
);
_writeLn('Starting shell...\r\n');
final session = await _client?.shell( final session = await _client?.shell(
pty: SSHPtyConfig( pty: SSHPtyConfig(
width: _terminal.viewWidth, width: _terminal.viewWidth,

View File

@@ -471,7 +471,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
@@ -481,7 +481,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.15; MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "Server Box"; PRODUCT_NAME = "Server Box";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -608,7 +608,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
@@ -618,7 +618,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.15; MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "Server Box"; PRODUCT_NAME = "Server Box";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -638,7 +638,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 876; CURRENT_PROJECT_VERSION = 877;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -649,7 +649,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.15; MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.876; MARKETING_VERSION = 1.0.877;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "Server Box"; PRODUCT_NAME = "Server Box";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

View File

@@ -262,10 +262,9 @@ packages:
dartssh2: dartssh2:
dependency: "direct main" dependency: "direct main"
description: description:
name: dartssh2 path: "../dartssh2"
sha256: "48d35ad9b697627b59f9ebeab4e4936266dc153cff96f02c997d3fe30df4d80a" relative: true
url: "https://pub.dev" source: path
source: hosted
version: "2.9.1-pre" version: "2.9.1-pre"
dbus: dbus:
dependency: transitive dependency: transitive

View File

@@ -19,11 +19,12 @@ dependencies:
after_layout: ^1.1.0 after_layout: ^1.1.0
url_launcher: ^6.1.8 url_launcher: ^6.1.8
countly_flutter: ^24.4.0 countly_flutter: ^24.4.0
dartssh2: ^2.9.1-pre dartssh2: #^2.9.1-pre
# newer version has some issues # newer version has some issues
# git: # git:
# ref: master # ref: master
# url: https://github.com/lollipopkit/dartssh2 # url: https://github.com/lollipopkit/dartssh2
path: ../dartssh2
logging: ^1.0.2 logging: ^1.0.2
circle_chart: circle_chart:
git: git: