Fix inconsistent displayed name (#13645)

* Add get_json_string_field helper

Introduce get_json_string_field in OrcaCloudServiceAgent.cpp to safely extract string fields from JSON objects.

* Add resolve_display_name helper

Introduce resolve_display_name to normalize provider metadata labels for the UI. The helper returns the first non-empty value from display_name, nickname, full_name, name, falling back to username, resolving human-facing label across varying provider payloads.

* Replace safe_str anonymous function

Replace get_json_string_field for better readability.

* Replace resolution flow for nickname with function

Consolidate both flows into one function for easier maintenance and more consistency.

* Update OrcaCloudServiceAgent.hpp

* Add OrcaCloudServiceAgent display name tests

Add unit tests verifying OrcaCloudServiceAgent resolves a user's display name from various session JSON shapes.
This commit is contained in:
Andrew
2026-05-13 17:58:08 +08:00
committed by GitHub
parent a167702038
commit 33be9775dc
3 changed files with 151 additions and 31 deletions

View File

@@ -74,6 +74,32 @@ constexpr const char* SECRET_STORE_SERVICE = "OrcaSlicer/Auth";
constexpr const char* SECRET_STORE_USER = "orca_refresh_token";
constexpr std::chrono::seconds TOKEN_REFRESH_SKEW{900}; // 15 minutes
// Return a JSON field only when it is present as a string. Missing or non-string values normalize to empty.
std::string get_json_string_field(const json& j, const std::string& key)
{
if (j.contains(key) && j[key].is_string()) {
return j[key].get<std::string>();
}
return "";
}
// Resolve the human-facing UI label from provider metadata.
std::string resolve_display_name(
const std::string& display_name,
const std::string& nickname,
const std::string& full_name,
const std::string& name,
const std::string& username)
{
// Providers and payload shapes do not all use the same display-name field.
// Fallback sequence: display_name -> nickname -> full_name -> name
if (!display_name.empty()) return display_name;
if (!nickname.empty()) return nickname;
if (!full_name.empty()) return full_name;
if (!name.empty()) return name;
return username;
}
std::string generate_uuid_for_setting_id(const std::string& name, const std::string& user_id = "")
{
if (name.empty()) {
@@ -1667,47 +1693,43 @@ bool OrcaCloudServiceAgent::set_user_session(const std::string& token,
bool OrcaCloudServiceAgent::set_user_session(const json& session_json, bool notify_login)
{
auto safe_str = [](const json& j, const std::string& key) -> std::string {
if (j.contains(key) && j[key].is_string()) return j[key].get<std::string>();
return "";
};
std::string access_token = safe_str(session_json, "access_token");
std::string access_token = get_json_string_field(session_json, "access_token");
if (access_token.empty()) {
access_token = safe_str(session_json, "token");
access_token = get_json_string_field(session_json, "token");
}
std::string refresh_token = safe_str(session_json, "refresh_token");
std::string refresh_token = get_json_string_field(session_json, "refresh_token");
std::string user_id, username, nickname, avatar;
if (session_json.contains("user") && session_json["user"].is_object()) {
// Nested format (Orca cloud / GoTrue response)
const auto& user = session_json["user"];
user_id = safe_str(user, "id");
user_id = get_json_string_field(user, "id");
if (user.contains("user_metadata") && user["user_metadata"].is_object()) {
const auto& meta = user["user_metadata"];
username = safe_str(meta, "username"); // Orca Cloud's unique username
username = get_json_string_field(meta, "username"); // Orca Cloud's unique username
nickname = safe_str(meta, "display_name"); // Orca Cloud's primary display name field
// Fallback to different name from different providers if display_name is not set
if (nickname.empty())
nickname = safe_str(meta, "full_name");
if (nickname.empty())
nickname = safe_str(meta, "name");
if (nickname.empty())
nickname = username;
avatar = safe_str(meta, "avatar_url");
// Orca Cloud's primary display name field is display_name.
// Fallback to different names from different providers if display_name is not set.
nickname = resolve_display_name(
get_json_string_field(meta, "display_name"),
get_json_string_field(meta, "nickname"),
get_json_string_field(meta, "full_name"),
get_json_string_field(meta, "name"),
username);
avatar = get_json_string_field(meta, "avatar_url");
}
} else {
// Flat format (WebView direct token flow)
user_id = safe_str(session_json, "user_id");
username = safe_str(session_json, "username");
nickname = safe_str(session_json, "display_name");
if(nickname.empty())
nickname = safe_str(session_json, "nickname");
avatar = safe_str(session_json, "avatar");
user_id = get_json_string_field(session_json, "user_id");
username = get_json_string_field(session_json, "username");
nickname = resolve_display_name(
get_json_string_field(session_json, "display_name"),
get_json_string_field(session_json, "nickname"),
get_json_string_field(session_json, "full_name"),
get_json_string_field(session_json, "name"),
username);
avatar = get_json_string_field(session_json, "avatar");
}
if (access_token.empty() || user_id.empty()) {