mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
#87 new: auto ask add system key (~/.ssh/id_rsa)
This commit is contained in:
@@ -128,6 +128,12 @@ abstract class S {
|
|||||||
/// **'Add private key'**
|
/// **'Add private key'**
|
||||||
String get addPrivateKey;
|
String get addPrivateKey;
|
||||||
|
|
||||||
|
/// No description provided for @addSystemPrivateKeyTip.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Currently don\'t have any private key, do you add the one that comes with the system (~/.ssh/id_rsa)?'**
|
||||||
|
String get addSystemPrivateKeyTip;
|
||||||
|
|
||||||
/// No description provided for @added2List.
|
/// No description provided for @added2List.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class SDe extends S {
|
|||||||
@override
|
@override
|
||||||
String get addPrivateKey => 'Private key hinzufügen';
|
String get addPrivateKey => 'Private key hinzufügen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addSystemPrivateKeyTip => 'Derzeit haben Sie keinen privaten Schlüssel, fügen Sie den Schlüssel hinzu, der mit dem System geliefert wird (~/.ssh/id_rsa)?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get added2List => 'Zur Aufgabenliste hinzugefügt';
|
String get added2List => 'Zur Aufgabenliste hinzugefügt';
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class SEn extends S {
|
|||||||
@override
|
@override
|
||||||
String get addPrivateKey => 'Add private key';
|
String get addPrivateKey => 'Add private key';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addSystemPrivateKeyTip => 'Currently don\'t have any private key, do you add the one that comes with the system (~/.ssh/id_rsa)?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get added2List => 'Added to task list';
|
String get added2List => 'Added to task list';
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class SId extends S {
|
|||||||
@override
|
@override
|
||||||
String get addPrivateKey => 'Tambahkan kunci pribadi';
|
String get addPrivateKey => 'Tambahkan kunci pribadi';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addSystemPrivateKeyTip => 'Saat ini tidak memiliki kunci privat, apakah Anda menambahkan kunci yang disertakan dengan sistem (~/.ssh/id_rsa)?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get added2List => 'Ditambahkan ke Daftar Tugas';
|
String get added2List => 'Ditambahkan ke Daftar Tugas';
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class SZh extends S {
|
|||||||
@override
|
@override
|
||||||
String get addPrivateKey => '添加一个私钥';
|
String get addPrivateKey => '添加一个私钥';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addSystemPrivateKeyTip => '当前没有任何私钥,是否添加系统自带的(~/.ssh/id_rsa)?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get added2List => '已添加至任务列表';
|
String get added2List => '已添加至任务列表';
|
||||||
|
|
||||||
@@ -701,6 +704,9 @@ class SZhTw extends SZh {
|
|||||||
@override
|
@override
|
||||||
String get addPrivateKey => '新增一個私鑰';
|
String get addPrivateKey => '新增一個私鑰';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addSystemPrivateKeyTip => '當前沒有任何私鑰,是否添加系統自帶的(~/.ssh/id_rsa)?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get added2List => '已添加至任務列表';
|
String get added2List => '已添加至任務列表';
|
||||||
|
|
||||||
|
|||||||
@@ -77,13 +77,12 @@ String pathJoin(String path1, String path2) {
|
|||||||
return path1 + (path1.endsWith('/') ? '' : '/') + path2;
|
return path1 + (path1.endsWith('/') ? '' : '/') + path2;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getHome() {
|
String? getHomeDir() {
|
||||||
String? home = "";
|
final envVars = Platform.environment;
|
||||||
Map<String, String> envVars = Platform.environment;
|
|
||||||
if (isMacOS || isLinux) {
|
if (isMacOS || isLinux) {
|
||||||
home = envVars['HOME'];
|
return envVars['HOME'];
|
||||||
} else if (isWindows) {
|
} else if (isWindows) {
|
||||||
home = envVars['UserProfile'];
|
return envVars['UserProfile'];
|
||||||
}
|
}
|
||||||
return home??"";
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ enum GenSSHClientStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getPrivateKey(String id) {
|
String getPrivateKey(String id) {
|
||||||
final key = locator<PrivateKeyStore>().get(id);
|
final pki = locator<PrivateKeyStore>().get(id);
|
||||||
if (key == null) {
|
if (pki == null) {
|
||||||
throw SSHErr(
|
throw SSHErr(
|
||||||
type: SSHErrType.noPrivateKey,
|
type: SSHErrType.noPrivateKey,
|
||||||
message: 'key [$id] not found',
|
message: 'key [$id] not found',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return key.privateKey;
|
return pki.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SSHClient> genClient(
|
Future<SSHClient> genClient(
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import 'dart:io';
|
|
||||||
import 'package:toolbox/core/utils/misc.dart' show getHome, pathJoin;
|
|
||||||
import 'package:toolbox/data/model/app/error.dart';
|
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
|
|
||||||
part 'private_key_info.g.dart';
|
part 'private_key_info.g.dart';
|
||||||
@@ -10,37 +7,25 @@ class PrivateKeyInfo {
|
|||||||
@HiveField(0)
|
@HiveField(0)
|
||||||
late String id;
|
late String id;
|
||||||
@HiveField(1)
|
@HiveField(1)
|
||||||
late String privateKey;
|
late String key;
|
||||||
|
@Deprecated('Never use this field')
|
||||||
@HiveField(2)
|
@HiveField(2)
|
||||||
late String password;
|
late String password;
|
||||||
|
|
||||||
PrivateKeyInfo(
|
PrivateKeyInfo({
|
||||||
this.id,
|
required this.id,
|
||||||
this.privateKey,
|
required this.key,
|
||||||
this.password,
|
});
|
||||||
);
|
|
||||||
PrivateKeyInfo.fromJson(Map<String, dynamic> json) {
|
PrivateKeyInfo.fromJson(Map<String, dynamic> json) {
|
||||||
id = json["id"].toString();
|
id = json["id"].toString();
|
||||||
privateKey = json["private_key"].toString();
|
key = json["private_key"].toString();
|
||||||
password = json["password"].toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
data["id"] = id;
|
data["id"] = id;
|
||||||
data["private_key"] = privateKey;
|
data["private_key"] = key;
|
||||||
data["password"] = password;
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SystemPrivateKeyInfo extends PrivateKeyInfo {
|
|
||||||
SystemPrivateKeyInfo() : super("System private key", "", "");
|
|
||||||
|
|
||||||
Future getKey() async {
|
|
||||||
File idRsaFile = File(pathJoin(getHome(), ".ssh/id_rsa"));
|
|
||||||
if (!await idRsaFile.exists()) {
|
|
||||||
this.privateKey="";
|
|
||||||
}
|
|
||||||
this.privateKey= await idRsaFile.readAsString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ class PrivateKeyInfoAdapter extends TypeAdapter<PrivateKeyInfo> {
|
|||||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||||
};
|
};
|
||||||
return PrivateKeyInfo(
|
return PrivateKeyInfo(
|
||||||
fields[0] as String,
|
id: fields[0] as String,
|
||||||
fields[1] as String,
|
key: fields[1] as String,
|
||||||
fields[2] as String,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,8 +29,9 @@ class PrivateKeyInfoAdapter extends TypeAdapter<PrivateKeyInfo> {
|
|||||||
..writeByte(0)
|
..writeByte(0)
|
||||||
..write(obj.id)
|
..write(obj.id)
|
||||||
..writeByte(1)
|
..writeByte(1)
|
||||||
..write(obj.privateKey)
|
..write(obj.key)
|
||||||
..writeByte(2)
|
..writeByte(2)
|
||||||
|
// ignore: deprecated_member_use_from_same_package
|
||||||
..write(obj.password);
|
..write(obj.password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,29 +4,33 @@ import 'package:toolbox/data/store/private_key.dart';
|
|||||||
import 'package:toolbox/locator.dart';
|
import 'package:toolbox/locator.dart';
|
||||||
|
|
||||||
class PrivateKeyProvider extends BusyProvider {
|
class PrivateKeyProvider extends BusyProvider {
|
||||||
List<PrivateKeyInfo> get infos => _infos;
|
List<PrivateKeyInfo> get pkis => _pkis;
|
||||||
final _store = locator<PrivateKeyStore>();
|
final _store = locator<PrivateKeyStore>();
|
||||||
late List<PrivateKeyInfo> _infos;
|
late List<PrivateKeyInfo> _pkis;
|
||||||
|
|
||||||
void loadData() {
|
void loadData() {
|
||||||
_infos = _store.fetch();
|
_pkis = _store.fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addInfo(PrivateKeyInfo info) {
|
void add(PrivateKeyInfo info) {
|
||||||
_infos.add(info);
|
_pkis.add(info);
|
||||||
_store.put(info);
|
_store.put(info);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void delInfo(PrivateKeyInfo info) {
|
void delete(PrivateKeyInfo info) {
|
||||||
_infos.removeWhere((e) => e.id == info.id);
|
_pkis.removeWhere((e) => e.id == info.id);
|
||||||
_store.delete(info);
|
_store.delete(info);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateInfo(PrivateKeyInfo old, PrivateKeyInfo newInfo) {
|
void update(PrivateKeyInfo old, PrivateKeyInfo newInfo) {
|
||||||
final idx = _infos.indexWhere((e) => e.id == old.id);
|
final idx = _pkis.indexWhere((e) => e.id == old.id);
|
||||||
_infos[idx] = newInfo;
|
if (idx == -1) {
|
||||||
|
_pkis.add(newInfo);
|
||||||
|
} else {
|
||||||
|
_pkis[idx] = newInfo;
|
||||||
|
}
|
||||||
_store.put(newInfo);
|
_store.put(newInfo);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'package:toolbox/core/persistant_store.dart';
|
import 'package:toolbox/core/persistant_store.dart';
|
||||||
import 'package:toolbox/data/model/server/private_key_info.dart';
|
import 'package:toolbox/data/model/server/private_key_info.dart';
|
||||||
import 'package:toolbox/core/utils/platform.dart';
|
|
||||||
|
|
||||||
class PrivateKeyStore extends PersistentStore {
|
class PrivateKeyStore extends PersistentStore {
|
||||||
late SystemPrivateKeyInfo systemPrivateKeyInfo;
|
|
||||||
void put(PrivateKeyInfo info) {
|
void put(PrivateKeyInfo info) {
|
||||||
box.put(info.id, info);
|
box.put(info.id, info);
|
||||||
}
|
}
|
||||||
@@ -18,19 +15,10 @@ class PrivateKeyStore extends PersistentStore {
|
|||||||
ps.add(s);
|
ps.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isLinux || isMacOS) {
|
|
||||||
SystemPrivateKeyInfo sysPk = SystemPrivateKeyInfo();
|
|
||||||
unawaited(sysPk.getKey());
|
|
||||||
systemPrivateKeyInfo = sysPk;
|
|
||||||
ps.add(sysPk);
|
|
||||||
}
|
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrivateKeyInfo? get(String? id) {
|
PrivateKeyInfo? get(String? id) {
|
||||||
if (id == "System private key") {
|
|
||||||
return this.systemPrivateKeyInfo;
|
|
||||||
}
|
|
||||||
if (id == null) return null;
|
if (id == null) return null;
|
||||||
return box.get(id);
|
return box.get(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"add": "Neu",
|
"add": "Neu",
|
||||||
"addAServer": "Server hinzufügen",
|
"addAServer": "Server hinzufügen",
|
||||||
"addPrivateKey": "Private key hinzufügen",
|
"addPrivateKey": "Private key hinzufügen",
|
||||||
|
"addSystemPrivateKeyTip": "Derzeit haben Sie keinen privaten Schlüssel, fügen Sie den Schlüssel hinzu, der mit dem System geliefert wird (~/.ssh/id_rsa)?",
|
||||||
"added2List": "Zur Aufgabenliste hinzugefügt",
|
"added2List": "Zur Aufgabenliste hinzugefügt",
|
||||||
"all": "Alle",
|
"all": "Alle",
|
||||||
"alreadyLastDir": "Bereits im letzten Verzeichnis.",
|
"alreadyLastDir": "Bereits im letzten Verzeichnis.",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"add": "Add",
|
"add": "Add",
|
||||||
"addAServer": "add a server",
|
"addAServer": "add a server",
|
||||||
"addPrivateKey": "Add private key",
|
"addPrivateKey": "Add private key",
|
||||||
|
"addSystemPrivateKeyTip": "Currently don't have any private key, do you add the one that comes with the system (~/.ssh/id_rsa)?",
|
||||||
"added2List": "Added to task list",
|
"added2List": "Added to task list",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"alreadyLastDir": "Already in last directory.",
|
"alreadyLastDir": "Already in last directory.",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"add": "Menambahkan",
|
"add": "Menambahkan",
|
||||||
"addAServer": "tambahkan server",
|
"addAServer": "tambahkan server",
|
||||||
"addPrivateKey": "Tambahkan kunci pribadi",
|
"addPrivateKey": "Tambahkan kunci pribadi",
|
||||||
|
"addSystemPrivateKeyTip": "Saat ini tidak memiliki kunci privat, apakah Anda menambahkan kunci yang disertakan dengan sistem (~/.ssh/id_rsa)?",
|
||||||
"added2List": "Ditambahkan ke Daftar Tugas",
|
"added2List": "Ditambahkan ke Daftar Tugas",
|
||||||
"all": "Semua",
|
"all": "Semua",
|
||||||
"alreadyLastDir": "Sudah di direktori terakhir.",
|
"alreadyLastDir": "Sudah di direktori terakhir.",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"add": "新增",
|
"add": "新增",
|
||||||
"addAServer": "添加服务器",
|
"addAServer": "添加服务器",
|
||||||
"addPrivateKey": "添加一个私钥",
|
"addPrivateKey": "添加一个私钥",
|
||||||
|
"addSystemPrivateKeyTip": "当前没有任何私钥,是否添加系统自带的(~/.ssh/id_rsa)?",
|
||||||
"added2List": "已添加至任务列表",
|
"added2List": "已添加至任务列表",
|
||||||
"all": "所有",
|
"all": "所有",
|
||||||
"alreadyLastDir": "已经是最上层目录了",
|
"alreadyLastDir": "已经是最上层目录了",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"add": "新增",
|
"add": "新增",
|
||||||
"addAServer": "新增服務器",
|
"addAServer": "新增服務器",
|
||||||
"addPrivateKey": "新增一個私鑰",
|
"addPrivateKey": "新增一個私鑰",
|
||||||
|
"addSystemPrivateKeyTip": "當前沒有任何私鑰,是否添加系統自帶的(~/.ssh/id_rsa)?",
|
||||||
"added2List": "已添加至任務列表",
|
"added2List": "已添加至任務列表",
|
||||||
"all": "所有",
|
"all": "所有",
|
||||||
"alreadyLastDir": "已經是最上層目錄了",
|
"alreadyLastDir": "已經是最上層目錄了",
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
|
|||||||
IconButton(
|
IconButton(
|
||||||
tooltip: _s.delete,
|
tooltip: _s.delete,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_provider.delInfo(widget.info!);
|
_provider.delete(widget.info!);
|
||||||
context.pop();
|
context.pop();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.delete))
|
icon: const Icon(Icons.delete))
|
||||||
@@ -100,9 +100,9 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
|
|||||||
setState(() {
|
setState(() {
|
||||||
_loading = centerSizedLoading;
|
_loading = centerSizedLoading;
|
||||||
});
|
});
|
||||||
final info = PrivateKeyInfo(name, key, '');
|
final info = PrivateKeyInfo(id: name, key: key);
|
||||||
try {
|
try {
|
||||||
info.privateKey = await compute(decyptPem, [key, pwd]);
|
info.key = await compute(decyptPem, [key, pwd]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showSnackBar(context, Text(e.toString()));
|
showSnackBar(context, Text(e.toString()));
|
||||||
rethrow;
|
rethrow;
|
||||||
@@ -112,9 +112,9 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (widget.info != null) {
|
if (widget.info != null) {
|
||||||
_provider.updateInfo(widget.info!, info);
|
_provider.update(widget.info!, info);
|
||||||
} else {
|
} else {
|
||||||
_provider.addInfo(info);
|
_provider.add(info);
|
||||||
}
|
}
|
||||||
context.pop();
|
context.pop();
|
||||||
},
|
},
|
||||||
@@ -194,8 +194,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage>
|
|||||||
Future<void> afterFirstLayout(BuildContext context) async {
|
Future<void> afterFirstLayout(BuildContext context) async {
|
||||||
if (widget.info != null) {
|
if (widget.info != null) {
|
||||||
_nameController.text = widget.info!.id;
|
_nameController.text = widget.info!.id;
|
||||||
_keyController.text = widget.info!.privateKey;
|
_keyController.text = widget.info!.key;
|
||||||
_pwdController.text = widget.info!.password;
|
|
||||||
} else {
|
} else {
|
||||||
final clipdata = ((await Clipboard.getData(_format))?.text ?? '').trim();
|
final clipdata = ((await Clipboard.getData(_format))?.text ?? '').trim();
|
||||||
if (clipdata.startsWith('-----BEGIN') && clipdata.endsWith('-----')) {
|
if (clipdata.startsWith('-----BEGIN') && clipdata.endsWith('-----')) {
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:toolbox/core/extension/navigator.dart';
|
||||||
|
import 'package:toolbox/core/utils/ui.dart';
|
||||||
|
import 'package:toolbox/data/store/private_key.dart';
|
||||||
|
import 'package:toolbox/locator.dart';
|
||||||
|
|
||||||
import '../../../core/route.dart';
|
import '../../../core/route.dart';
|
||||||
|
import '../../../core/utils/misc.dart';
|
||||||
|
import '../../../core/utils/platform.dart';
|
||||||
|
import '../../../data/model/server/private_key_info.dart';
|
||||||
import '../../../data/provider/private_key.dart';
|
import '../../../data/provider/private_key.dart';
|
||||||
import '../../../data/res/ui.dart';
|
import '../../../data/res/ui.dart';
|
||||||
import 'edit.dart';
|
import 'edit.dart';
|
||||||
@@ -24,6 +33,13 @@ class _PrivateKeyListState extends State<PrivateKeysListPage> {
|
|||||||
_s = S.of(context)!;
|
_s = S.of(context)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
autoAddSystemPriavteKey();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@@ -44,21 +60,21 @@ class _PrivateKeyListState extends State<PrivateKeysListPage> {
|
|||||||
Widget _buildBody() {
|
Widget _buildBody() {
|
||||||
return Consumer<PrivateKeyProvider>(
|
return Consumer<PrivateKeyProvider>(
|
||||||
builder: (_, key, __) {
|
builder: (_, key, __) {
|
||||||
if (key.infos.isEmpty) {
|
if (key.pkis.isEmpty) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(_s.noSavedPrivateKey),
|
child: Text(_s.noSavedPrivateKey),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
padding: const EdgeInsets.all(13),
|
padding: const EdgeInsets.all(13),
|
||||||
itemCount: key.infos.length,
|
itemCount: key.pkis.length,
|
||||||
itemBuilder: (context, idx) {
|
itemBuilder: (context, idx) {
|
||||||
return RoundRectCard(
|
return RoundRectCard(
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(key.infos[idx].id),
|
title: Text(key.pkis[idx].id),
|
||||||
trailing: TextButton(
|
trailing: TextButton(
|
||||||
onPressed: () => AppRoute(
|
onPressed: () => AppRoute(
|
||||||
PrivateKeyEditPage(info: key.infos[idx]),
|
PrivateKeyEditPage(info: key.pkis[idx]),
|
||||||
'private key edit page',
|
'private key edit page',
|
||||||
).go(context),
|
).go(context),
|
||||||
child: Text(_s.edit),
|
child: Text(_s.edit),
|
||||||
@@ -70,4 +86,40 @@ class _PrivateKeyListState extends State<PrivateKeysListPage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void autoAddSystemPriavteKey() {
|
||||||
|
final store = locator<PrivateKeyStore>();
|
||||||
|
// Only trigger on desktop platform and no private key saved
|
||||||
|
if (isDesktop && store.box.keys.isEmpty) {
|
||||||
|
final home = getHomeDir();
|
||||||
|
if (home == null) return;
|
||||||
|
final idRsaFile = File(pathJoin(home, '.ssh/id_rsa'));
|
||||||
|
if (!idRsaFile.existsSync()) return;
|
||||||
|
final sysPk = PrivateKeyInfo(
|
||||||
|
id: 'system',
|
||||||
|
key: idRsaFile.readAsStringSync(),
|
||||||
|
);
|
||||||
|
showRoundDialog(
|
||||||
|
context: context,
|
||||||
|
title: Text(_s.attention),
|
||||||
|
child: Text(_s.addSystemPrivateKeyTip),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.pop();
|
||||||
|
AppRoute(
|
||||||
|
PrivateKeyEditPage(info: sysPk),
|
||||||
|
'private key edit page',
|
||||||
|
).go(context);
|
||||||
|
},
|
||||||
|
child: Text(_s.ok),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(_s.cancel),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,17 +200,17 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
|
|||||||
Widget _buildKeyAuth() {
|
Widget _buildKeyAuth() {
|
||||||
return Consumer<PrivateKeyProvider>(
|
return Consumer<PrivateKeyProvider>(
|
||||||
builder: (_, key, __) {
|
builder: (_, key, __) {
|
||||||
for (var item in key.infos) {
|
for (var item in key.pkis) {
|
||||||
if (item.id == widget.spi?.pubKeyId) {
|
if (item.id == widget.spi?.pubKeyId) {
|
||||||
_pubKeyIndex ??= key.infos.indexOf(item);
|
_pubKeyIndex ??= key.pkis.indexOf(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final tiles = key.infos
|
final tiles = key.pkis
|
||||||
.map(
|
.map(
|
||||||
(e) => ListTile(
|
(e) => ListTile(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
title: Text(e.id, textAlign: TextAlign.start),
|
title: Text(e.id, textAlign: TextAlign.start),
|
||||||
trailing: _buildRadio(key.infos.indexOf(e), e),
|
trailing: _buildRadio(key.pkis.indexOf(e), e),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|||||||
Reference in New Issue
Block a user