Merge pull request #1155 from 21pages/flutter_desktop

password
This commit is contained in:
RustDesk 2022-08-02 22:45:43 +08:00 committed by GitHub
commit 0dd55d6ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 353 additions and 70 deletions

View File

@ -8,6 +8,7 @@ import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/desktop/pages/connection_page.dart'; import 'package:flutter_hbb/desktop/pages/connection_page.dart';
import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart'; import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart';
import 'package:flutter_hbb/models/model.dart'; import 'package:flutter_hbb/models/model.dart';
import 'package:flutter_hbb/models/server_model.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -127,9 +128,8 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
), ),
TextFormField( TextFormField(
controller: model.serverId, controller: model.serverId,
decoration: InputDecoration( enableInteractiveSelection: true,
enabled: false, readOnly: true,
),
), ),
], ],
), ),
@ -248,8 +248,34 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
translate("Password"), translate("Password"),
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500), style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
), ),
TextFormField( Row(
controller: model.serverPasswd, children: [
Expanded(
child: TextFormField(
controller: model.serverPasswd,
enableInteractiveSelection: true,
readOnly: true,
),
),
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
gFFI.setByName("temporary_password");
},
),
FutureBuilder<Widget>(
future: buildPasswordPopupMenu(context),
builder: (context, snapshot) {
if (snapshot.hasError) {
print("${snapshot.error}");
}
if (snapshot.hasData) {
return snapshot.data!;
} else {
return Offstage();
}
})
],
), ),
], ],
), ),
@ -260,6 +286,83 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
); );
} }
Future<Widget> buildPasswordPopupMenu(BuildContext context) async {
var position;
return GestureDetector(
onTapDown: (detail) {
final x = detail.globalPosition.dx;
final y = detail.globalPosition.dy;
position = RelativeRect.fromLTRB(x, y, x, y);
},
onTap: () async {
var method = (String text, String value) => PopupMenuItem(
child: Row(
children: [
Offstage(
offstage: gFFI.serverModel.verificationMethod != value,
child: Icon(Icons.check)),
Text(
text,
),
],
),
value: value,
onTap: () => gFFI.serverModel.verificationMethod = value,
);
final temporary_enabled =
gFFI.serverModel.verificationMethod != kUsePermanentPassword;
var menu = [
method(translate("Use temporary password"), kUseTemporaryPassword),
method(translate("Use permanent password"), kUsePermanentPassword),
method(translate("Use both passwords"), kUseBothPasswords),
PopupMenuItem(
child: Text(translate("Set permanent password")),
value: 'set-permanent-password',
enabled: gFFI.serverModel.verificationMethod !=
kUseTemporaryPassword),
PopupMenuItem(
child: PopupMenuButton(
child: Text("Set temporary password length"),
itemBuilder: (context) => ["6", "8", "10"]
.map((e) => PopupMenuItem(
child: Row(
children: [
Offstage(
offstage: gFFI.serverModel
.temporaryPasswordLength !=
e,
child: Icon(Icons.check)),
Text(
e,
),
],
),
value: e,
onTap: () {
if (gFFI.serverModel.temporaryPasswordLength !=
e) {
gFFI.serverModel.temporaryPasswordLength = e;
gFFI.setByName("temporary_password");
}
},
))
.toList(),
enabled: temporary_enabled,
),
value: 'set-temporary-password-length',
enabled: temporary_enabled),
];
final v =
await showMenu(context: context, position: position, items: menu);
if (v != null) {
if (v == "set-permanent-password") {
setPasswordDialog();
}
}
},
child: Icon(Icons.edit));
}
buildTip(BuildContext context) { buildTip(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
@ -295,15 +398,15 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
Text(translate("Control Remote Desktop")), Text(translate("Control Remote Desktop")),
Form( Form(
child: Column( child: Column(
children: [ children: [
TextFormField( TextFormField(
controller: TextEditingController(), controller: TextEditingController(),
inputFormatters: [ inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r"[0-9]")) FilteringTextInputFormatter.allow(RegExp(r"[0-9]"))
],
)
], ],
)) )
],
))
], ],
), ),
); );
@ -320,7 +423,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
case "quit": case "quit":
exit(0); exit(0);
case "show": case "show":
// windowManager.show(); // windowManager.show();
break; break;
default: default:
break; break;
@ -398,7 +501,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
return isPositive return isPositive
? TextStyle() ? TextStyle()
: TextStyle( : TextStyle(
color: Colors.redAccent, decoration: TextDecoration.lineThrough); color: Colors.redAccent, decoration: TextDecoration.lineThrough);
} }
PopupMenuItem<String> genAudioInputPopupMenuItem() { PopupMenuItem<String> genAudioInputPopupMenuItem() {
@ -410,29 +513,29 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
future: gFFI.getAudioInputs(), future: gFFI.getAudioInputs(),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
final inputs = snapshot.data!; final inputs = snapshot.data!.toList();
if (Platform.isWindows) { if (Platform.isWindows) {
inputs.insert(0, translate("System Sound")); inputs.insert(0, translate("System Sound"));
} }
var inputList = inputs var inputList = inputs
.map((e) => PopupMenuItem( .map((e) => PopupMenuItem(
child: Row( child: Row(
children: [ children: [
Obx(() => Offstage( Obx(() => Offstage(
offstage: defaultInput.value != e, offstage: defaultInput.value != e,
child: Icon(Icons.check))), child: Icon(Icons.check))),
Expanded( Expanded(
child: Tooltip( child: Tooltip(
message: e, message: e,
child: Text( child: Text(
"$e", "$e",
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
))), ))),
], ],
), ),
value: e, value: e,
)) ))
.toList(); .toList();
inputList.insert( inputList.insert(
0, 0,
@ -553,7 +656,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
void changeServer() async { void changeServer() async {
Map<String, dynamic> oldOptions = Map<String, dynamic> oldOptions =
jsonDecode(await gFFI.bind.mainGetOptions()); jsonDecode(await gFFI.bind.mainGetOptions());
print("${oldOptions}"); print("${oldOptions}");
String idServer = oldOptions['custom-rendezvous-server'] ?? ""; String idServer = oldOptions['custom-rendezvous-server'] ?? "";
var idServerMsg = ""; var idServerMsg = "";
@ -592,7 +695,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
decoration: InputDecoration( decoration: InputDecoration(
border: OutlineInputBorder(), border: OutlineInputBorder(),
errorText: errorText:
idServerMsg.isNotEmpty ? idServerMsg : null), idServerMsg.isNotEmpty ? idServerMsg : null),
controller: TextEditingController(text: idServer), controller: TextEditingController(text: idServer),
), ),
), ),
@ -645,7 +748,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
decoration: InputDecoration( decoration: InputDecoration(
border: OutlineInputBorder(), border: OutlineInputBorder(),
errorText: errorText:
apiServerMsg.isNotEmpty ? apiServerMsg : null), apiServerMsg.isNotEmpty ? apiServerMsg : null),
controller: TextEditingController(text: apiServer), controller: TextEditingController(text: apiServer),
), ),
), ),
@ -761,7 +864,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
void changeWhiteList() async { void changeWhiteList() async {
Map<String, dynamic> oldOptions = Map<String, dynamic> oldOptions =
jsonDecode(await gFFI.bind.mainGetOptions()); jsonDecode(await gFFI.bind.mainGetOptions());
var newWhiteList = ((oldOptions['whitelist'] ?? "") as String).split(','); var newWhiteList = ((oldOptions['whitelist'] ?? "") as String).split(',');
var newWhiteListField = newWhiteList.join('\n'); var newWhiteListField = newWhiteList.join('\n');
var msg = ""; var msg = "";
@ -817,7 +920,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
// pass // pass
} else { } else {
final ips = final ips =
newWhiteListField.trim().split(RegExp(r"[\s,;\n]+")); newWhiteListField.trim().split(RegExp(r"[\s,;\n]+"));
// test ip // test ip
final ipMatch = RegExp(r"^\d+\.\d+\.\d+\.\d+$"); final ipMatch = RegExp(r"^\d+\.\d+\.\d+\.\d+$");
for (final ip in ips) { for (final ip in ips) {
@ -977,7 +1080,8 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
return; return;
} }
} }
await gFFI.bind.mainSetSocks(proxy: proxy, username: username, password: password); await gFFI.bind.mainSetSocks(
proxy: proxy, username: username, password: password);
close(); close();
}, },
child: Text(translate("OK"))), child: Text(translate("OK"))),
@ -1204,4 +1308,107 @@ Future<bool> loginDialog() async {
); );
}); });
return completer.future; return completer.future;
} }
void setPasswordDialog() {
final pw = gFFI.getByName("permanent_password");
final p0 = TextEditingController(text: pw);
final p1 = TextEditingController(text: pw);
var errMsg0 = "";
var errMsg1 = "";
DialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate("Set Password")),
content: ConstrainedBox(
constraints: BoxConstraints(minWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text(
"${translate('Password')}:",
textAlign: TextAlign.start,
).marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
errorText: errMsg0.isNotEmpty ? errMsg0 : null),
controller: p0,
),
),
],
),
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('Confirmation')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
errorText: errMsg1.isNotEmpty ? errMsg1 : null),
controller: p1,
),
),
],
),
SizedBox(
height: 4.0,
),
],
),
),
actions: [
TextButton(
onPressed: () {
close();
},
child: Text(translate("Cancel"))),
TextButton(
onPressed: () {
setState(() {
errMsg0 = "";
errMsg1 = "";
});
final pass = p0.text.trim();
if (pass.length < 6) {
setState(() {
errMsg0 = translate("Too short, at least 6 characters.");
});
return;
}
if (p1.text.trim() != pass) {
setState(() {
errMsg1 = translate("The confirmation is not identical.");
});
return;
}
gFFI.setByName("permanent_password", pass);
close();
},
child: Text(translate("OK"))),
],
);
});
}

View File

@ -23,6 +23,7 @@ class ServerModel with ChangeNotifier {
bool _fileOk = false; bool _fileOk = false;
int _connectStatus = 0; // Rendezvous Server status int _connectStatus = 0; // Rendezvous Server status
String _verificationMethod = ""; String _verificationMethod = "";
String _temporaryPasswordLength = "";
late String _emptyIdShow; late String _emptyIdShow;
late final TextEditingController _serverId; late final TextEditingController _serverId;
@ -42,7 +43,35 @@ class ServerModel with ChangeNotifier {
int get connectStatus => _connectStatus; int get connectStatus => _connectStatus;
String get verificationMethod => _verificationMethod; String get verificationMethod {
final index = [
kUseTemporaryPassword,
kUsePermanentPassword,
kUseBothPasswords
].indexOf(_verificationMethod);
if (index < 0) {
_verificationMethod = kUseBothPasswords;
}
return _verificationMethod;
}
set verificationMethod(String method) {
_verificationMethod = method;
gFFI.setOption("verification-method", method);
}
String get temporaryPasswordLength {
final lengthIndex = ["6", "8", "10"].indexOf(_temporaryPasswordLength);
if (lengthIndex < 0) {
_temporaryPasswordLength = "6";
}
return _temporaryPasswordLength;
}
set temporaryPasswordLength(String length) {
_temporaryPasswordLength = length;
gFFI.setOption("temporary-password-length", length);
}
TextEditingController get serverId => _serverId; TextEditingController get serverId => _serverId;
@ -127,16 +156,26 @@ class ServerModel with ChangeNotifier {
updatePasswordModel() { updatePasswordModel() {
var update = false; var update = false;
final temporaryPassword = gFFI.getByName("temporary_password"); final temporaryPassword = gFFI.getByName("temporary_password");
final verificationMethod = gFFI.getByName("option", "verification-method"); final verificationMethod = gFFI.getOption("verification-method");
final temporaryPasswordLength = gFFI.getOption("temporary-password-length");
final oldPwdText = _serverPasswd.text;
if (_serverPasswd.text != temporaryPassword) { if (_serverPasswd.text != temporaryPassword) {
_serverPasswd.text = temporaryPassword; _serverPasswd.text = temporaryPassword;
}
if (verificationMethod == kUsePermanentPassword) {
_serverPasswd.text = '-';
}
if (oldPwdText != _serverPasswd.text) {
update = true; update = true;
} }
if (_verificationMethod != verificationMethod) { if (_verificationMethod != verificationMethod) {
_verificationMethod = verificationMethod; _verificationMethod = verificationMethod;
update = true; update = true;
} }
if (_temporaryPasswordLength != temporaryPasswordLength) {
_temporaryPasswordLength = temporaryPasswordLength;
update = true;
}
if (update) { if (update) {
notifyListeners(); notifyListeners();
} }
@ -272,7 +311,7 @@ class ServerModel with ChangeNotifier {
Future<bool> setPermanentPassword(String newPW) async { Future<bool> setPermanentPassword(String newPW) async {
parent.target?.setByName("permanent_password", newPW); parent.target?.setByName("permanent_password", newPW);
await Future.delayed(Duration(milliseconds: 500)); await Future.delayed(Duration(milliseconds: 500));
final pw = parent.target?.getByName("permanent_password", newPW); final pw = parent.target?.getByName("permanent_password");
if (newPW == pw) { if (newPW == pw) {
return true; return true;
} else { } else {

View File

@ -24,8 +24,7 @@ use crate::ui_interface::{
get_async_job_status, get_connect_status, get_fav, get_id, get_lan_peers, get_license, get_async_job_status, get_connect_status, get_fav, get_id, get_lan_peers, get_license,
get_local_option, get_options, get_peer, get_peer_option, get_socks, get_sound_inputs, get_local_option, get_options, get_peer, get_peer_option, get_socks, get_sound_inputs,
get_uuid, get_version, has_rendezvous_service, is_ok_change_id, post_request, set_local_option, get_uuid, get_version, has_rendezvous_service, is_ok_change_id, post_request, set_local_option,
set_options, set_peer_option, set_socks, store_fav, temporary_password, test_if_valid_server, set_options, set_peer_option, set_socks, store_fav, test_if_valid_server, using_public_server,
using_public_server,
}; };
fn initialize(app_dir: &str) { fn initialize(app_dir: &str) {
@ -613,7 +612,7 @@ unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *co
} }
"option" => { "option" => {
if let Ok(arg) = arg.to_str() { if let Ok(arg) = arg.to_str() {
res = Config::get_option(arg); res = ui_interface::get_option(arg.to_owned());
} }
} }
// "image_quality" => { // "image_quality" => {
@ -642,7 +641,10 @@ unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *co
res = ui_interface::get_id(); res = ui_interface::get_id();
} }
"temporary_password" => { "temporary_password" => {
res = password_security::temporary_password(); res = ui_interface::temporary_password();
}
"permanent_password" => {
res = ui_interface::permanent_password();
} }
"connect_statue" => { "connect_statue" => {
res = ONLINE res = ONLINE
@ -829,7 +831,7 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) {
if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) { if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
if let Some(name) = m.get("name") { if let Some(name) = m.get("name") {
if let Some(value) = m.get("value") { if let Some(value) = m.get("value") {
Config::set_option(name.to_owned(), value.to_owned()); ui_interface::set_option(name.to_owned(), value.to_owned());
if name == "custom-rendezvous-server" { if name == "custom-rendezvous-server" {
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
crate::rendezvous_mediator::RendezvousMediator::restart(); crate::rendezvous_mediator::RendezvousMediator::restart();
@ -1049,6 +1051,12 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) {
connection_manager::close_conn(id); connection_manager::close_conn(id);
}; };
} }
"temporary_password" => {
ui_interface::update_temporary_password();
}
"permanent_password" => {
ui_interface::set_permanent_password(value.to_owned());
}
_ => { _ => {
log::error!("Unknown name of set_by_name: {}", name); log::error!("Unknown name of set_by_name: {}", name);
} }

View File

@ -32,9 +32,9 @@ use crate::ui_interface::{
is_login_wayland, is_ok_change_id, is_process_trusted, is_rdp_service_open, is_share_rdp, is_login_wayland, is_ok_change_id, is_process_trusted, is_rdp_service_open, is_share_rdp,
is_xfce, modify_default_login, new_remote, open_url, peer_has_password, permanent_password, is_xfce, modify_default_login, new_remote, open_url, peer_has_password, permanent_password,
post_request, recent_sessions_updated, remove_peer, run_without_install, set_local_option, post_request, recent_sessions_updated, remove_peer, run_without_install, set_local_option,
set_option, set_options, set_peer_option, set_remote_id, set_share_rdp, set_socks, set_option, set_options, set_peer_option, set_permanent_password, set_remote_id, set_share_rdp,
show_run_without_install, store_fav, t, temporary_password, test_if_valid_server, update_me, set_socks, show_run_without_install, store_fav, t, temporary_password, test_if_valid_server,
update_temporary_password, using_public_server, update_me, update_temporary_password, using_public_server,
}; };
mod cm; mod cm;
@ -205,7 +205,7 @@ impl UI {
} }
fn set_permanent_password(&self, password: String) { fn set_permanent_password(&self, password: String) {
allow_err!(ipc::set_permanent_password(password)); set_permanent_password(password);
} }
fn get_remote_id(&mut self) -> String { fn get_remote_id(&mut self) -> String {

View File

@ -5,11 +5,13 @@ use std::{
time::SystemTime, time::SystemTime,
}; };
#[cfg(any(target_os = "android", target_os = "ios"))]
use hbb_common::password_security;
use hbb_common::{ use hbb_common::{
allow_err, allow_err,
config::{self, Config, LocalConfig, PeerConfig, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT}, config::{self, Config, LocalConfig, PeerConfig, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT},
futures::future::join_all, futures::future::join_all,
log, password_security, log,
protobuf::Message as _, protobuf::Message as _,
rendezvous_proto::*, rendezvous_proto::*,
sleep, sleep,
@ -129,7 +131,10 @@ pub fn get_license() -> String {
} }
pub fn get_option(key: String) -> String { pub fn get_option(key: String) -> String {
get_option_(&key) #[cfg(any(target_os = "android", target_os = "ios"))]
return Config::get_option(arg);
#[cfg(not(any(target_os = "android", target_os = "ios")))]
return get_option_(&key);
} }
fn get_option_(key: &str) -> String { fn get_option_(key: &str) -> String {
@ -243,20 +248,25 @@ pub fn set_options(m: HashMap<String, String>) {
} }
pub fn set_option(key: String, value: String) { pub fn set_option(key: String, value: String) {
let mut options = OPTIONS.lock().unwrap(); #[cfg(any(target_os = "android", target_os = "ios"))]
#[cfg(target_os = "macos")] Config::set_option(name.to_owned(), value.to_owned());
if &key == "stop-service" { #[cfg(not(any(target_os = "android", target_os = "ios")))]
let is_stop = value == "Y"; {
if is_stop && crate::platform::macos::uninstall() { let mut options = OPTIONS.lock().unwrap();
return; #[cfg(target_os = "macos")]
if &key == "stop-service" {
let is_stop = value == "Y";
if is_stop && crate::platform::macos::uninstall() {
return;
}
} }
if value.is_empty() {
options.remove(&key);
} else {
options.insert(key.clone(), value.clone());
}
ipc::set_options(options.clone()).ok();
} }
if value.is_empty() {
options.remove(&key);
} else {
options.insert(key.clone(), value.clone());
}
ipc::set_options(options.clone()).ok();
} }
pub fn install_path() -> String { pub fn install_path() -> String {
@ -358,16 +368,32 @@ pub fn get_connect_status() -> Status {
res res
} }
pub fn temporary_password() -> String {
#[cfg(any(target_os = "android", target_os = "ios"))]
return password_security::temporary_password();
#[cfg(not(any(target_os = "android", target_os = "ios")))]
return TEMPORARY_PASSWD.lock().unwrap().clone();
}
pub fn update_temporary_password() { pub fn update_temporary_password() {
#[cfg(any(target_os = "android", target_os = "ios"))]
password_security::update_temporary_password();
#[cfg(not(any(target_os = "android", target_os = "ios")))]
allow_err!(ipc::update_temporary_password()); allow_err!(ipc::update_temporary_password());
} }
pub fn permanent_password() -> String { pub fn permanent_password() -> String {
ipc::get_permanent_password() #[cfg(any(target_os = "android", target_os = "ios"))]
return Config::get_permanent_password();
#[cfg(not(any(target_os = "android", target_os = "ios")))]
return ipc::get_permanent_password();
} }
pub fn temporary_password() -> String { pub fn set_permanent_password(password: String) {
password_security::temporary_password() #[cfg(any(target_os = "android", target_os = "ios"))]
Config::set_permanent_password(&password);
#[cfg(not(any(target_os = "android", target_os = "ios")))]
allow_err!(ipc::set_permanent_password(password));
} }
pub fn get_peer(id: String) -> PeerConfig { pub fn get_peer(id: String) -> PeerConfig {
@ -680,6 +706,8 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
Ok(Some(ipc::Data::Config((name, Some(value))))) => { Ok(Some(ipc::Data::Config((name, Some(value))))) => {
if name == "id" { if name == "id" {
id = value; id = value;
} else if name == "temporary-password" {
*TEMPORARY_PASSWD.lock().unwrap() = value;
} }
} }
Ok(Some(ipc::Data::OnlineStatus(Some((mut x, c))))) => { Ok(Some(ipc::Data::OnlineStatus(Some((mut x, c))))) => {
@ -699,6 +727,7 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
c.send(&ipc::Data::OnlineStatus(None)).await.ok(); c.send(&ipc::Data::OnlineStatus(None)).await.ok();
c.send(&ipc::Data::Options(None)).await.ok(); c.send(&ipc::Data::Options(None)).await.ok();
c.send(&ipc::Data::Config(("id".to_owned(), None))).await.ok(); c.send(&ipc::Data::Config(("id".to_owned(), None))).await.ok();
c.send(&ipc::Data::Config(("temporary-password".to_owned(), None))).await.ok();
} }
} }
} }