mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-08-19 01:26:35 +08:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d0453fff3 | ||
|
|
8a9775a571 | ||
|
|
7f4f1882ae | ||
|
|
23e24e3d47 | ||
|
|
7e1b9cb00e | ||
|
|
0c70acbdbf | ||
|
|
fcbbb0f51c | ||
|
|
f4be0700bf | ||
|
|
a45670b04d | ||
|
|
ff329cae81 | ||
|
|
092664784e | ||
|
|
1709eb0efb |
@@ -260,7 +260,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build CrossDesk
|
- name: Build CrossDesk
|
||||||
run: |
|
run: |
|
||||||
xmake f --target_minver=${MACOSX_DEPLOYMENT_TARGET} --CROSSDESK_VERSION=${VERSION_NUM} --USE_CUDA=true -y
|
xmake f --target_minver=${MACOSX_DEPLOYMENT_TARGET} --CROSSDESK_VERSION=${VERSION_NUM} --USE_CUDA=false -y
|
||||||
xmake b -vy crossdesk
|
xmake b -vy crossdesk
|
||||||
|
|
||||||
- name: Package CrossDesk app
|
- name: Package CrossDesk app
|
||||||
|
|||||||
@@ -1342,33 +1342,42 @@ void GuiApplication::BindMainCallbacks() {
|
|||||||
if (password.size() != 6) {
|
if (password.size() != 6) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::memset(password_saved_, 0, sizeof(password_saved_));
|
|
||||||
std::strncpy(password_saved_, password.c_str(),
|
|
||||||
sizeof(password_saved_) - 1);
|
|
||||||
|
|
||||||
if (config_center_->IsSelfHosted()) {
|
if (!peer_ || !signal_connected_) {
|
||||||
std::string identity = self_hosted_id_;
|
offline_warning_text_ =
|
||||||
if (const auto at = identity.find('@'); at != std::string::npos) {
|
localization::signal_disconnected[localization_language_index_];
|
||||||
identity.resize(at);
|
show_offline_warning_window_ = true;
|
||||||
}
|
return true;
|
||||||
if (identity.empty()) {
|
|
||||||
identity = client_id_;
|
|
||||||
}
|
|
||||||
identity += "@" + password;
|
|
||||||
std::memset(self_hosted_id_, 0, sizeof(self_hosted_id_));
|
|
||||||
std::strncpy(self_hosted_id_, identity.c_str(),
|
|
||||||
sizeof(self_hosted_id_) - 1);
|
|
||||||
} else {
|
|
||||||
const std::string identity = std::string(client_id_) + "@" + password;
|
|
||||||
std::memset(client_id_with_password_, 0,
|
|
||||||
sizeof(client_id_with_password_));
|
|
||||||
std::strncpy(client_id_with_password_, identity.c_str(),
|
|
||||||
sizeof(client_id_with_password_) - 1);
|
|
||||||
}
|
}
|
||||||
settings_.Save();
|
|
||||||
if (peer_) {
|
std::string request_id;
|
||||||
LeaveConnection(peer_, client_id_);
|
{
|
||||||
DestroyPeer(&peer_);
|
std::lock_guard<std::mutex> lock(password_change_mutex_);
|
||||||
|
if (password_change_pending_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
request_id = std::to_string(++next_password_change_request_id_);
|
||||||
|
password_change_pending_ = true;
|
||||||
|
password_change_result_ready_ = false;
|
||||||
|
password_change_succeeded_ = false;
|
||||||
|
password_change_requested_at_ = std::chrono::steady_clock::now();
|
||||||
|
pending_password_change_request_id_ = request_id;
|
||||||
|
pending_local_password_ = password;
|
||||||
|
password_change_error_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const nlohmann::json request = {{"type", "change_password"},
|
||||||
|
{"request_id", request_id},
|
||||||
|
{"new_password", password}};
|
||||||
|
const std::string message = request.dump();
|
||||||
|
if (SendSignalMessage(peer_, message.data(), message.size()) != 0) {
|
||||||
|
std::lock_guard<std::mutex> lock(password_change_mutex_);
|
||||||
|
password_change_pending_ = false;
|
||||||
|
pending_password_change_request_id_.clear();
|
||||||
|
pending_local_password_.clear();
|
||||||
|
offline_warning_text_ =
|
||||||
|
localization::signal_disconnected[localization_language_index_];
|
||||||
|
show_offline_warning_window_ = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -1778,6 +1787,7 @@ void GuiApplication::Tick() {
|
|||||||
slint::quit_event_loop();
|
slint::quit_event_loop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
HandlePasswordChangeResult();
|
||||||
if (!peer_) {
|
if (!peer_) {
|
||||||
CreateConnectionPeer();
|
CreateConnectionPeer();
|
||||||
}
|
}
|
||||||
@@ -1852,6 +1862,76 @@ void GuiApplication::Tick() {
|
|||||||
SyncServerWindow();
|
SyncServerWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GuiApplication::HandlePasswordChangeResult() {
|
||||||
|
bool succeeded = false;
|
||||||
|
std::string new_password;
|
||||||
|
std::string error;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(password_change_mutex_);
|
||||||
|
if (password_change_pending_ && !password_change_result_ready_ &&
|
||||||
|
std::chrono::steady_clock::now() - password_change_requested_at_ >=
|
||||||
|
std::chrono::seconds(10)) {
|
||||||
|
password_change_result_ready_ = true;
|
||||||
|
password_change_succeeded_ = false;
|
||||||
|
password_change_error_ = "Server did not respond";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password_change_result_ready_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
succeeded = password_change_succeeded_;
|
||||||
|
new_password = pending_local_password_;
|
||||||
|
error = password_change_error_;
|
||||||
|
password_change_pending_ = false;
|
||||||
|
password_change_result_ready_ = false;
|
||||||
|
password_change_succeeded_ = false;
|
||||||
|
pending_password_change_request_id_.clear();
|
||||||
|
pending_local_password_.clear();
|
||||||
|
password_change_error_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!succeeded) {
|
||||||
|
LOG_WARN("Password change failed: {}", error);
|
||||||
|
offline_warning_text_ = localization::failed[localization_language_index_];
|
||||||
|
if (!error.empty()) {
|
||||||
|
offline_warning_text_ += ": " + error;
|
||||||
|
}
|
||||||
|
show_offline_warning_window_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memset(password_saved_, 0, sizeof(password_saved_));
|
||||||
|
std::strncpy(password_saved_, new_password.c_str(),
|
||||||
|
sizeof(password_saved_) - 1);
|
||||||
|
|
||||||
|
const std::string identity = std::string(client_id_) + "@" + new_password;
|
||||||
|
if (config_center_->IsSelfHosted()) {
|
||||||
|
std::memset(self_hosted_id_, 0, sizeof(self_hosted_id_));
|
||||||
|
std::strncpy(self_hosted_id_, identity.c_str(),
|
||||||
|
sizeof(self_hosted_id_) - 1);
|
||||||
|
} else {
|
||||||
|
std::memset(client_id_with_password_, 0,
|
||||||
|
sizeof(client_id_with_password_));
|
||||||
|
std::strncpy(client_id_with_password_, identity.c_str(),
|
||||||
|
sizeof(client_id_with_password_) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings_.Save() != 0) {
|
||||||
|
LOG_ERROR("Password changed on server but could not be saved locally");
|
||||||
|
offline_warning_text_ = localization::failed[localization_language_index_];
|
||||||
|
show_offline_warning_window_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("Password changed successfully for [{}]", client_id_);
|
||||||
|
if (peer_) {
|
||||||
|
LeaveConnection(peer_, client_id_);
|
||||||
|
DestroyPeer(&peer_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GuiApplication::UpdateLocalization() {
|
void GuiApplication::UpdateLocalization() {
|
||||||
const int language =
|
const int language =
|
||||||
localization::detail::ClampLanguageIndex(localization_language_index_);
|
localization::detail::ClampLanguageIndex(localization_language_index_);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ private:
|
|||||||
void BindStreamCallbacks();
|
void BindStreamCallbacks();
|
||||||
void BindServerCallbacks();
|
void BindServerCallbacks();
|
||||||
void Tick();
|
void Tick();
|
||||||
|
void HandlePasswordChangeResult();
|
||||||
void SyncMainWindow();
|
void SyncMainWindow();
|
||||||
void SyncConnectionDialog();
|
void SyncConnectionDialog();
|
||||||
void SyncPlatformDialogs();
|
void SyncPlatformDialogs();
|
||||||
|
|||||||
@@ -134,14 +134,7 @@ int SettingsManager::Load() {
|
|||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
const char *at_pos = std::strchr(owner_.client_id_with_password_, '@');
|
ActivateCachedPublicIdentity();
|
||||||
if (at_pos != nullptr) {
|
|
||||||
const std::string id(owner_.client_id_with_password_,
|
|
||||||
at_pos - owner_.client_id_with_password_);
|
|
||||||
const std::string password(at_pos + 1);
|
|
||||||
CopyString(owner_.client_id_, id.c_str());
|
|
||||||
CopyString(owner_.password_saved_, password.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
owner_.thumbnail_ =
|
owner_.thumbnail_ =
|
||||||
std::make_shared<Thumbnail>(owner_.cache_path_ + "/thumbnails/",
|
std::make_shared<Thumbnail>(owner_.cache_path_ + "/thumbnails/",
|
||||||
@@ -195,6 +188,8 @@ bool SettingsManager::LoadCachedSelfHostedIdentity() {
|
|||||||
std::lock_guard<std::mutex> lock(cache_mutex_);
|
std::lock_guard<std::mutex> lock(cache_mutex_);
|
||||||
if (!ReadV2Locked() || cache_v2_.self_hosted_id[0] == '\0') {
|
if (!ReadV2Locked() || cache_v2_.self_hosted_id[0] == '\0') {
|
||||||
std::memset(owner_.self_hosted_id_, 0, sizeof(owner_.self_hosted_id_));
|
std::memset(owner_.self_hosted_id_, 0, sizeof(owner_.self_hosted_id_));
|
||||||
|
std::memset(owner_.client_id_, 0, sizeof(owner_.client_id_));
|
||||||
|
std::memset(owner_.password_saved_, 0, sizeof(owner_.password_saved_));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +207,26 @@ bool SettingsManager::LoadCachedSelfHostedIdentity() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SettingsManager::ActivateCachedPublicIdentity() {
|
||||||
|
if (owner_.client_id_with_password_[0] == '\0') {
|
||||||
|
std::memset(owner_.client_id_, 0, sizeof(owner_.client_id_));
|
||||||
|
std::memset(owner_.password_saved_, 0, sizeof(owner_.password_saved_));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *at_pos = std::strchr(owner_.client_id_with_password_, '@');
|
||||||
|
if (at_pos == nullptr) {
|
||||||
|
CopyString(owner_.client_id_, owner_.client_id_with_password_);
|
||||||
|
std::memset(owner_.password_saved_, 0, sizeof(owner_.password_saved_));
|
||||||
|
} else {
|
||||||
|
const std::string id(owner_.client_id_with_password_,
|
||||||
|
at_pos - owner_.client_id_with_password_);
|
||||||
|
CopyString(owner_.client_id_, id.c_str());
|
||||||
|
CopyString(owner_.password_saved_, at_pos + 1);
|
||||||
|
}
|
||||||
|
return owner_.client_id_[0] != '\0';
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsManager::PersistSelfHostedIdentity(const char *client_id) {
|
void SettingsManager::PersistSelfHostedIdentity(const char *client_id) {
|
||||||
if (!client_id) {
|
if (!client_id) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ public:
|
|||||||
// Loads the cached self-hosted identity into the owner's active connection
|
// Loads the cached self-hosted identity into the owner's active connection
|
||||||
// fields. Returns true only when a non-empty identity was restored.
|
// fields. Returns true only when a non-empty identity was restored.
|
||||||
bool LoadCachedSelfHostedIdentity();
|
bool LoadCachedSelfHostedIdentity();
|
||||||
|
// Restores the public-server identity kept in the in-memory cache fields.
|
||||||
|
// This must run when switching away from a self-hosted server so signal
|
||||||
|
// callbacks are matched against the identity used by the replacement peer.
|
||||||
|
bool ActivateCachedPublicIdentity();
|
||||||
void PersistSelfHostedIdentity(const char *client_id);
|
void PersistSelfHostedIdentity(const char *client_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ int GuiRuntime::CreateConnectionPeer() {
|
|||||||
signal_server_ip = config_center_->GetDefaultServerHost();
|
signal_server_ip = config_center_->GetDefaultServerHost();
|
||||||
signal_server_port = config_center_->GetDefaultSignalServerPort();
|
signal_server_port = config_center_->GetDefaultSignalServerPort();
|
||||||
coturn_server_port = config_center_->GetDefaultCoturnServerPort();
|
coturn_server_port = config_center_->GetDefaultCoturnServerPort();
|
||||||
|
settings_.ActivateCachedPublicIdentity();
|
||||||
params_.user_id = client_id_with_password_;
|
params_.user_id = client_id_with_password_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,12 +95,11 @@ int GuiRuntime::CreateConnectionPeer() {
|
|||||||
sizeof(params_.turn_server_ip) - 1);
|
sizeof(params_.turn_server_ip) - 1);
|
||||||
params_.turn_server_ip[sizeof(params_.turn_server_ip) - 1] = '\0';
|
params_.turn_server_ip[sizeof(params_.turn_server_ip) - 1] = '\0';
|
||||||
params_.turn_server_port = coturn_server_port;
|
params_.turn_server_port = coturn_server_port;
|
||||||
strncpy((char *)params_.turn_server_username, "crossdesk",
|
// TURN credentials are issued by the signaling server after login. Keep the
|
||||||
sizeof(params_.turn_server_username) - 1);
|
// initial values empty so a reusable static password is never embedded in
|
||||||
params_.turn_server_username[sizeof(params_.turn_server_username) - 1] = '\0';
|
// the client binary.
|
||||||
strncpy((char *)params_.turn_server_password, "crossdeskpw",
|
params_.turn_server_username[0] = '\0';
|
||||||
sizeof(params_.turn_server_password) - 1);
|
params_.turn_server_password[0] = '\0';
|
||||||
params_.turn_server_password[sizeof(params_.turn_server_password) - 1] = '\0';
|
|
||||||
|
|
||||||
strncpy(params_.log_path, dll_log_path_.c_str(),
|
strncpy(params_.log_path, dll_log_path_.c_str(),
|
||||||
sizeof(params_.log_path) - 1);
|
sizeof(params_.log_path) - 1);
|
||||||
@@ -126,6 +126,11 @@ int GuiRuntime::CreateConnectionPeer() {
|
|||||||
|
|
||||||
params_.user_data = &peer_events_;
|
params_.user_data = &peer_events_;
|
||||||
|
|
||||||
|
// The previous peer may have left a terminal status behind. Reset it before
|
||||||
|
// Init() starts emitting callbacks for the newly selected server.
|
||||||
|
signal_connected_ = false;
|
||||||
|
signal_status_ = SignalStatus::SignalConnecting;
|
||||||
|
|
||||||
peer_ = CreatePeer(¶ms_);
|
peer_ = CreatePeer(¶ms_);
|
||||||
if (peer_) {
|
if (peer_) {
|
||||||
LOG_INFO("Create peer instance [{}] successful", client_id_);
|
LOG_INFO("Create peer instance [{}] successful", client_id_);
|
||||||
|
|||||||
@@ -85,6 +85,38 @@ void PeerEventHandler::OnSignalMessage(const char* message, size_t size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (type == "change_password") {
|
||||||
|
std::lock_guard<std::mutex> lock(runtime->password_change_mutex_);
|
||||||
|
if (!runtime->password_change_pending_) {
|
||||||
|
LOG_WARN("Ignore unexpected password change response");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!j.contains("request_id") || !j["request_id"].is_string() ||
|
||||||
|
j["request_id"].get<std::string>() !=
|
||||||
|
runtime->pending_password_change_request_id_) {
|
||||||
|
LOG_WARN("Ignore password change response with unexpected request id");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j.contains("user_id") && j["user_id"].is_string()) {
|
||||||
|
const std::string response_user_id = j["user_id"].get<std::string>();
|
||||||
|
if (!response_user_id.empty() &&
|
||||||
|
response_user_id != runtime->client_id_) {
|
||||||
|
LOG_WARN("Ignore password change response for unexpected id [{}]",
|
||||||
|
response_user_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime->password_change_succeeded_ =
|
||||||
|
j.contains("status") && j["status"].is_string() &&
|
||||||
|
j["status"].get<std::string>() == "success";
|
||||||
|
runtime->password_change_error_ =
|
||||||
|
j.contains("reason") && j["reason"].is_string()
|
||||||
|
? j["reason"].get<std::string>()
|
||||||
|
: "Password change failed";
|
||||||
|
runtime->password_change_result_ready_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,18 @@ struct UserSettingsState {
|
|||||||
bool show_file_browser_ = true;
|
bool show_file_browser_ = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PasswordChangeState {
|
||||||
|
std::mutex password_change_mutex_;
|
||||||
|
uint64_t next_password_change_request_id_ = 0;
|
||||||
|
bool password_change_pending_ = false;
|
||||||
|
bool password_change_result_ready_ = false;
|
||||||
|
bool password_change_succeeded_ = false;
|
||||||
|
std::chrono::steady_clock::time_point password_change_requested_at_;
|
||||||
|
std::string pending_password_change_request_id_;
|
||||||
|
std::string pending_local_password_;
|
||||||
|
std::string password_change_error_;
|
||||||
|
};
|
||||||
|
|
||||||
struct ConnectionState {
|
struct ConnectionState {
|
||||||
using RemoteSessionMap =
|
using RemoteSessionMap =
|
||||||
std::unordered_map<std::string, RemoteSessionPtr>;
|
std::unordered_map<std::string, RemoteSessionPtr>;
|
||||||
@@ -180,6 +192,7 @@ struct RuntimeState : InfrastructureState,
|
|||||||
PeerState,
|
PeerState,
|
||||||
PlatformIntegrationState,
|
PlatformIntegrationState,
|
||||||
UserSettingsState,
|
UserSettingsState,
|
||||||
|
PasswordChangeState,
|
||||||
ConnectionState {};
|
ConnectionState {};
|
||||||
|
|
||||||
} // namespace crossdesk::gui_detail
|
} // namespace crossdesk::gui_detail
|
||||||
|
|||||||
+1
-1
Submodule submodules/minirtc updated: 50ca51ecc1...145f75481f
+3
-1
@@ -80,7 +80,9 @@ function setup_platform_settings()
|
|||||||
|
|
||||||
add_cxflags("-Wno-unused-variable")
|
add_cxflags("-Wno-unused-variable")
|
||||||
elseif is_os("macosx") then
|
elseif is_os("macosx") then
|
||||||
add_ldflags("-Wl,-ld_classic")
|
if is_arch("x86_64") then
|
||||||
|
add_ldflags("-Wl,-ld_classic")
|
||||||
|
end
|
||||||
add_cxflags("-Wno-unused-variable")
|
add_cxflags("-Wno-unused-variable")
|
||||||
add_frameworks("Cocoa", "OpenGL", "IOSurface", "ScreenCaptureKit",
|
add_frameworks("Cocoa", "OpenGL", "IOSurface", "ScreenCaptureKit",
|
||||||
"AVFoundation", "CoreMedia", "CoreVideo", "CoreAudio",
|
"AVFoundation", "CoreMedia", "CoreVideo", "CoreAudio",
|
||||||
|
|||||||
Reference in New Issue
Block a user