Compare commits

..
Author SHA1 Message Date
ksmithandClaude Sonnet 5 0cdf930303 Fix connect-time username prompt being unreachable for SSH/RDP
validateProfileForConnect() still hard-failed with a blocking
QMessageBox for a blank SSH/RDP username, running before
requestConnectOptions() ever got a chance to prompt for it inline --
so the connect-time username prompt added for issue #21 was dead code
in practice; users just got told to go edit the profile instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 08:28:41 -06:00
ksmithandClaude Sonnet 5 7559488ceb Bump version to v2026.9.16.3
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 08:18:22 -06:00
ksmithandClaude Sonnet 5 ab4a34fc01 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 <noreply@anthropic.com>
2026-09-16 08:17:05 -06:00
5 changed files with 32 additions and 19 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.21) cmake_minimum_required(VERSION 3.21)
project(OrbitHub VERSION 2026.9.16.2 LANGUAGES CXX) project(OrbitHub VERSION 2026.9.16.4 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
+18
View File
@@ -175,6 +175,24 @@ Delivered:
cleanly rather than sending Apple auth a blank username. The value is 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 kept on the tab's in-memory profile copy for its lifetime, not written
back to the saved profile 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
- A third, independent username check was still live even after the two
above were removed: `SessionTab::validateProfileForConnect()` (run at
the very top of `connectSession()`/`reconnectSession()`, before
`requestConnectOptions()` ever gets a chance to run its async prompt)
had its own hard-fail "SSH/RDP username is required" `QMessageBox`,
so a blank-username profile still couldn't connect at all -- it just
told the user to go edit the profile instead of ever prompting inline.
Removed; connect-time prompting is now the only username gate for
SSH/RDP
- Robustness fix: an unrecognized `FramebufferUpdate` rectangle encoding - Robustness fix: an unrecognized `FramebufferUpdate` rectangle encoding
used to abort the connection generically; `kAnnouncedEncodings` is now used to abort the connection generically; `kAnnouncedEncodings` is now
the single source of truth for what `SetEncodings` announces and what the single source of truth for what `SetEncodings` announces and what
-7
View File
@@ -235,13 +235,6 @@ bool isProfileValid(const Profile& profile, QString* error)
} }
const QString protocol = normalizedProtocol(profile.protocol); 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); const QString authMode = normalizedAuthMode(protocol, profile.authMode);
if (protocol == QStringLiteral("SSH") && authMode == QStringLiteral("Private Key") if (protocol == QStringLiteral("SSH") && authMode == QStringLiteral("Private Key")
+4 -8
View File
@@ -1181,14 +1181,10 @@ bool SessionTab::validateProfileForConnect()
return false; return false;
} }
if ((m_profile.protocol.compare(QStringLiteral("SSH"), Qt::CaseInsensitive) == 0 // SSH/RDP no longer hard-require a username here -- a blank one is
|| m_profile.protocol.compare(QStringLiteral("RDP"), Qt::CaseInsensitive) == 0) // handled by requestConnectOptions() prompting for it inline at connect
&& m_profile.username.trimmed().isEmpty()) { // time (see issue #21). Do not re-add a check here without also
QMessageBox::warning(this, // updating that flow.
QStringLiteral("Connect"),
QStringLiteral("%1 username is required.").arg(m_profile.protocol));
return false;
}
return true; return true;
} }
+9 -3
View File
@@ -48,7 +48,7 @@ private slots:
void createProfileRejectsMissingName(); void createProfileRejectsMissingName();
void createProfileRejectsMissingHost(); void createProfileRejectsMissingHost();
void createProfileRejectsInvalidPort(); void createProfileRejectsInvalidPort();
void createProfileRejectsMissingUsernameForSsh(); void createProfileAllowsMissingUsernameForSsh();
void createProfileRejectsMissingPrivateKeyForKeyAuth(); void createProfileRejectsMissingPrivateKeyForKeyAuth();
void createProfileRejectsDuplicateName(); void createProfileRejectsDuplicateName();
void updateProfilePersistsChanges(); void updateProfilePersistsChanges();
@@ -156,11 +156,17 @@ void TestProfileRepository::createProfileRejectsInvalidPort()
QVERIFY(!m_repo->createProfile(profile).has_value()); 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 profile = makeSshProfile();
profile.username.clear(); 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() void TestProfileRepository::createProfileRejectsMissingPrivateKeyForKeyAuth()