From ab4a34fc018a9bc145747d167dbe924f434df20e Mon Sep 17 00:00:00 2001 From: Keith Smith Date: Wed, 16 Sep 2026 08:17:05 -0600 Subject: [PATCH] Fix mRemoteNG import failing on entries without a username The previous username relaxation only touched ProfileDialog's own save-time validation. ProfileRepository::isProfileValid() had the identical "username required for SSH/RDP" check independently, called directly by insertProfile()/updateProfile() -- exactly the path mRemoteNG import uses, since it builds Profile objects and inserts them directly rather than going through the dialog. Every imported SSH/RDP entry without a recorded username was rejected outright. Co-Authored-By: Claude Sonnet 5 --- docs/PROGRESS.md | 9 +++++++++ src/profile_repository.cpp | 7 ------- tests/test_profile_repository.cpp | 12 +++++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 3b6c827..d5421ad 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -175,6 +175,15 @@ Delivered: cleanly rather than sending Apple auth a blank username. The value is kept on the tab's in-memory profile copy for its lifetime, not written back to the saved profile +- The blank-username relaxation above initially only covered + `ProfileDialog`'s own save-time validation; `ProfileRepository:: + isProfileValid()` had the identical "username required for SSH/RDP" + check independently, called directly by `insertProfile()`/ + `updateProfile()` -- which is exactly the path mRemoteNG import uses + (it builds `Profile` objects and inserts them directly, never going + through the dialog), so importing any SSH/RDP entry without a + username still failed outright until this second check was found and + removed too - Robustness fix: an unrecognized `FramebufferUpdate` rectangle encoding used to abort the connection generically; `kAnnouncedEncodings` is now the single source of truth for what `SetEncodings` announces and what diff --git a/src/profile_repository.cpp b/src/profile_repository.cpp index 0072412..284b2ab 100644 --- a/src/profile_repository.cpp +++ b/src/profile_repository.cpp @@ -235,13 +235,6 @@ bool isProfileValid(const Profile& profile, QString* error) } const QString protocol = normalizedProtocol(profile.protocol); - if ((protocol == QStringLiteral("SSH") || protocol == QStringLiteral("RDP")) - && profile.username.trimmed().isEmpty()) { - if (error != nullptr) { - *error = QStringLiteral("Username is required for %1 profiles.").arg(protocol); - } - return false; - } const QString authMode = normalizedAuthMode(protocol, profile.authMode); if (protocol == QStringLiteral("SSH") && authMode == QStringLiteral("Private Key") diff --git a/tests/test_profile_repository.cpp b/tests/test_profile_repository.cpp index 78ba71e..6cdebf2 100644 --- a/tests/test_profile_repository.cpp +++ b/tests/test_profile_repository.cpp @@ -48,7 +48,7 @@ private slots: void createProfileRejectsMissingName(); void createProfileRejectsMissingHost(); void createProfileRejectsInvalidPort(); - void createProfileRejectsMissingUsernameForSsh(); + void createProfileAllowsMissingUsernameForSsh(); void createProfileRejectsMissingPrivateKeyForKeyAuth(); void createProfileRejectsDuplicateName(); void updateProfilePersistsChanges(); @@ -156,11 +156,17 @@ void TestProfileRepository::createProfileRejectsInvalidPort() QVERIFY(!m_repo->createProfile(profile).has_value()); } -void TestProfileRepository::createProfileRejectsMissingUsernameForSsh() +void TestProfileRepository::createProfileAllowsMissingUsernameForSsh() { + // SSH/RDP no longer require a username at save time (issue #21) -- + // among other things, this unblocks importing mRemoteNG entries that + // don't have one recorded, which used to fail outright. The user is + // asked for it at connect time instead (see SessionTab). Profile profile = makeSshProfile(); profile.username.clear(); - QVERIFY(!m_repo->createProfile(profile).has_value()); + const auto created = m_repo->createProfile(profile); + QVERIFY(created.has_value()); + QVERIFY(created->username.isEmpty()); } void TestProfileRepository::createProfileRejectsMissingPrivateKeyForKeyAuth()