[fix] persist successful connections without saved passwords

This commit is contained in:
dijunkun
2026-10-12 03:06:33 +08:00
parent e156ff5277
commit c9e0078bfb
6 changed files with 50 additions and 13 deletions
@@ -206,6 +206,35 @@ int GuiRuntime::CreateConnectionPeer() {
}
void GuiRuntime::HandleRecentConnections() {
if (thumbnail_ && session_cleanup_tasks_.empty()) {
std::vector<std::shared_ptr<RemoteSession>> sessions;
{
std::shared_lock lock(remote_sessions_mutex_);
for (const auto& [_, props] : remote_sessions_)
if (props && !props->closing_ && props->was_connected_ &&
props->recent_connection_dirty_.exchange(false))
sessions.push_back(props);
}
for (const auto& props : sessions) {
std::string host_name;
HostPlatform platform;
{
std::lock_guard lock(props->remote_version_mutex_);
host_name = props->remote_host_name_;
platform = props->recent_platform_;
}
// Record a successful connection before a preview or host info arrives.
// The close path still updates its final thumbnail. Remember password
// controls only credential storage, not whether this device is listed.
if (thumbnail_->SaveToThumbnail(
nullptr, 0, 0, props->remote_id_, host_name,
props->remember_password_ ? props->remote_password_ : "",
platform) == 0)
reload_recent_connections_ = true;
else
LOG_ERROR("[{}] Failed to save recent connection", props->remote_id_);
}
}
if (session_cleanup_tasks_.empty() && reload_recent_connections_ && thumbnail_) {
uint32_t now_time = SDL_GetTicks();
if (now_time - recent_connection_image_save_time_ >= 50) {
@@ -357,17 +357,21 @@ void PeerEventHandler::OnReceiveDataBuffer(
}
}
// client mode
if (props && props->remote_host_name_.empty()) {
props->remote_host_name_ = std::string(remote_action.i.host_name,
remote_action.i.host_name_size);
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
if (props) {
std::lock_guard lock(props->remote_version_mutex_);
if (props->remote_host_name_.empty()) {
props->remote_host_name_ = std::string(remote_action.i.host_name,
remote_action.i.host_name_size);
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
for (int i = 0; i < remote_action.i.display_num; i++) {
props->display_info_list_.push_back(
DisplayInfo(remote_action.i.display_list[i],
remote_action.i.left[i], remote_action.i.top[i],
remote_action.i.right[i], remote_action.i.bottom[i]));
for (int i = 0; i < remote_action.i.display_num; i++) {
props->display_info_list_.push_back(
DisplayInfo(remote_action.i.display_list[i],
remote_action.i.left[i], remote_action.i.top[i],
remote_action.i.right[i], remote_action.i.bottom[i]));
}
}
props->recent_connection_dirty_ = true;
}
FreeRemoteAction(remote_action);
} else {
@@ -308,6 +308,7 @@ void PeerEventHandler::OnConnectionStatus(ConnectionStatus status,
}
props->connection_established_ = true;
props->was_connected_ = true;
props->recent_connection_dirty_ = true;
runtime->start_keyboard_capturer_ = true;
break;
}
@@ -91,6 +91,8 @@ struct RemoteSession {
SignalStatus signal_status_ = SignalStatus::SignalClosed;
bool connection_established_ = false;
std::atomic<bool> was_connected_{false};
// Transport callbacks publish changes; the UI thread persists history.
std::atomic<bool> recent_connection_dirty_{false};
bool rejoin_ = false;
bool net_traffic_stats_button_pressed_ = false;
bool enable_mouse_control_ = true;
+3 -4
View File
@@ -203,16 +203,15 @@ int Thumbnail::SaveToThumbnail(const char* nv12, int width, int height,
const std::string& password,
HostPlatform platform) {
std::lock_guard lock(mutex_);
// Preserve the existing opt-in via Remember password for recent connections.
if (password.empty()) return 0;
// Successful connections are history even without saved credentials.
if (!IsRemoteId(remote_id)) return -1;
RecentConnection connection;
ReadRecord(std::filesystem::path(save_path_) / (remote_id + ".json"),
&connection);
connection.remote_id = remote_id;
connection.remote_host_name = host_name;
if (!host_name.empty()) connection.remote_host_name = host_name;
connection.password = password;
connection.remember_password = true;
connection.remember_password = !password.empty();
if (platform != HostPlatform::Unknown) connection.platform = platform;
if (!WriteRecord(connection)) return -1;
+2
View File
@@ -41,6 +41,8 @@ class Thumbnail {
// Serialized with writes so disabling also clears any in-flight preview.
int SetSavePreviews(bool enabled);
// Also records metadata without an image. Empty password means do not store
// credentials (and clears any remembered password from a previous session).
int SaveToThumbnail(const char* nv12, int width, int height,
const std::string& remote_id,
const std::string& host_name,