RelayClient: fix syntax error in savedServers(); strip trailing slash on relay URLs
This commit is contained in:
parent
9bcef4c0a9
commit
f270350ae6
1 changed files with 26 additions and 41 deletions
|
|
@ -14,23 +14,22 @@
|
|||
RelayClient::RelayClient(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_nam(new QNetworkAccessManager(this))
|
||||
, m_settings(new QSettings(QStringLiteral("WildDragon"), QStringLiteral("DragonMoonlight"), this))
|
||||
, m_settings(new QSettings(QStringLiteral("WildDragon"),
|
||||
QStringLiteral("DragonMoonlight"), this))
|
||||
{
|
||||
}
|
||||
|
||||
RelayClient::~RelayClient() = default;
|
||||
|
||||
// ─── URL helpers ──────────────────────────────────────────────────────────────
|
||||
|
||||
QUrl RelayClient::apiUrl(const QString &path) const
|
||||
{
|
||||
QUrl u = m_relayUrl;
|
||||
u.setPath(u.path() + path);
|
||||
QString base = u.path();
|
||||
while (base.endsWith(QLatin1Char('/'))) base.chop(1);
|
||||
u.setPath(base + path);
|
||||
return u;
|
||||
}
|
||||
|
||||
// ─── Auth-header injection ────────────────────────────────────────────────
|
||||
|
||||
QNetworkReply *RelayClient::authedGet(const QString &path)
|
||||
{
|
||||
QNetworkRequest req(apiUrl(path));
|
||||
|
|
@ -53,8 +52,6 @@ QNetworkReply *RelayClient::authedDelete(const QString &path)
|
|||
return m_nam->deleteResource(req);
|
||||
}
|
||||
|
||||
// ─── login() ─────────────────────────────────────────────────────────────────
|
||||
|
||||
void RelayClient::login(const QUrl &relayUrl, const QString &username, const QString &password)
|
||||
{
|
||||
m_relayUrl = relayUrl;
|
||||
|
|
@ -62,7 +59,8 @@ void RelayClient::login(const QUrl &relayUrl, const QString &username, const QSt
|
|||
m_jwt.clear();
|
||||
|
||||
QNetworkRequest req(apiUrl(QStringLiteral("/api/auth/login")));
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader,
|
||||
QByteArrayLiteral("application/json"));
|
||||
|
||||
QJsonObject body;
|
||||
body[QStringLiteral("username")] = username;
|
||||
|
|
@ -87,7 +85,8 @@ void RelayClient::onLoginReply(QNetworkReply *reply, const QString &username,
|
|||
const QJsonObject json = QJsonDocument::fromJson(reply->readAll()).object();
|
||||
const QString token = json[QStringLiteral("token")].toString();
|
||||
if (token.isEmpty()) {
|
||||
const QString err = json[QStringLiteral("error")].toString(QStringLiteral("Unknown error"));
|
||||
const QString err = json[QStringLiteral("error")]
|
||||
.toString(QStringLiteral("Unknown error"));
|
||||
emit loginFailed(err);
|
||||
return;
|
||||
}
|
||||
|
|
@ -98,11 +97,8 @@ void RelayClient::onLoginReply(QNetworkReply *reply, const QString &username,
|
|||
emit loginSucceeded();
|
||||
}
|
||||
|
||||
// ─── provisionVPN() ───────────────────────────────────────────────────────────
|
||||
|
||||
void RelayClient::provisionVPN(const QString &deviceName)
|
||||
{
|
||||
// Use the machine's host name if the caller didn't provide one.
|
||||
const QString device = deviceName.isEmpty()
|
||||
? QSysInfo::machineHostName()
|
||||
: deviceName;
|
||||
|
|
@ -128,14 +124,14 @@ void RelayClient::onProvisionReply(QNetworkReply *reply)
|
|||
const QJsonObject json = QJsonDocument::fromJson(reply->readAll()).object();
|
||||
const QString conf = json[QStringLiteral("conf")].toString();
|
||||
if (conf.isEmpty()) {
|
||||
const QString err = json[QStringLiteral("error")].toString(QStringLiteral("No conf in response"));
|
||||
const QString err = json[QStringLiteral("error")]
|
||||
.toString(QStringLiteral("No conf in response"));
|
||||
emit vpnProvisionFailed(err);
|
||||
return;
|
||||
}
|
||||
|
||||
m_vpnPeerId = json[QStringLiteral("id")].toInt(-1);
|
||||
|
||||
// Persist peer ID so we can revoke it even after a restart.
|
||||
m_settings->setValue(QStringLiteral("vpn/peer_id"), m_vpnPeerId);
|
||||
m_settings->setValue(QStringLiteral("vpn/relay_url"), m_relayUrl.toString());
|
||||
|
||||
|
|
@ -144,20 +140,18 @@ void RelayClient::onProvisionReply(QNetworkReply *reply)
|
|||
emit vpnProvisioned(vpnConf);
|
||||
}
|
||||
|
||||
// ─── revokeVPN() ─────────────────────────────────────────────────────────────
|
||||
|
||||
void RelayClient::revokeVPN()
|
||||
{
|
||||
if (m_vpnPeerId < 0) {
|
||||
// Try to load from settings (post-restart cleanup).
|
||||
m_vpnPeerId = m_settings->value(QStringLiteral("vpn/peer_id"), -1).toInt();
|
||||
}
|
||||
if (m_vpnPeerId < 0) {
|
||||
emit vpnRevoked(); // nothing to do
|
||||
emit vpnRevoked();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString path = QStringLiteral("/api/vpn/peer/") + QString::number(m_vpnPeerId);
|
||||
const QString path = QStringLiteral("/api/vpn/peer/")
|
||||
+ QString::number(m_vpnPeerId);
|
||||
QNetworkReply *reply = authedDelete(path);
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
reply->deleteLater();
|
||||
|
|
@ -175,8 +169,6 @@ void RelayClient::onRevokeReply(QNetworkReply *reply)
|
|||
emit vpnRevoked();
|
||||
}
|
||||
|
||||
// ─── fetchHosts() ─────────────────────────────────────────────────────────────
|
||||
|
||||
void RelayClient::fetchHosts()
|
||||
{
|
||||
QNetworkReply *reply = authedGet(QStringLiteral("/api/hosts"));
|
||||
|
|
@ -202,7 +194,6 @@ void RelayClient::onHostsReply(QNetworkReply *reply)
|
|||
h.ip = obj[QStringLiteral("ip")].toString();
|
||||
h.port = obj[QStringLiteral("port")].toInt(47984);
|
||||
|
||||
// Parse displays array if present
|
||||
const QJsonArray displaysArr = obj[QStringLiteral("displays")].toArray();
|
||||
for (const QJsonValue &dv : displaysArr) {
|
||||
const QJsonObject displayObj = dv.toObject();
|
||||
|
|
@ -216,7 +207,8 @@ void RelayClient::onHostsReply(QNetworkReply *reply)
|
|||
}
|
||||
|
||||
if (h.displays.isEmpty()) {
|
||||
qWarning() << "Host" << h.name << "has no display data in relay response";
|
||||
qDebug() << "Host" << h.name
|
||||
<< "has no display data in relay response (older Artemis?)";
|
||||
}
|
||||
|
||||
if (!h.ip.isEmpty())
|
||||
|
|
@ -225,21 +217,15 @@ void RelayClient::onHostsReply(QNetworkReply *reply)
|
|||
emit hostsReady(hosts);
|
||||
}
|
||||
|
||||
// ─── Persistence ──────────────────────────────────────────────────────────────
|
||||
|
||||
void RelayClient::persistJwt()
|
||||
{
|
||||
// NOTE: QSettings on macOS stores in ~/Library/Preferences.
|
||||
// The JWT has a limited lifetime — don't rely on it across sessions;
|
||||
// the app will re-authenticate on next launch using saved credentials.
|
||||
m_settings->setValue(QStringLiteral("auth/relay_url"), m_relayUrl.toString());
|
||||
m_settings->setValue(QStringLiteral("auth/username"), m_username);
|
||||
// We do NOT persist the JWT itself or the password.
|
||||
}
|
||||
|
||||
void RelayClient::loadJwt()
|
||||
{
|
||||
// Intentionally empty — re-auth on each launch for security.
|
||||
// Intentionally empty - we re-auth on each launch for security.
|
||||
}
|
||||
|
||||
void RelayClient::saveServer(const QString &label, const QUrl &url,
|
||||
|
|
@ -248,8 +234,7 @@ void RelayClient::saveServer(const QString &label, const QUrl &url,
|
|||
m_settings->beginGroup(QStringLiteral("servers/") + label);
|
||||
m_settings->setValue(QStringLiteral("url"), url.toString());
|
||||
m_settings->setValue(QStringLiteral("username"), username);
|
||||
// password stored in the system keychain would be better; plain QSettings
|
||||
// as a baseline — replace with QKeychain in production.
|
||||
// TODO: replace with QKeychain so the password isn't stored in plaintext.
|
||||
m_settings->setValue(QStringLiteral("password"), password);
|
||||
m_settings->endGroup();
|
||||
}
|
||||
|
|
@ -260,13 +245,13 @@ QList<RelayClient::SavedServer> RelayClient::savedServers() const
|
|||
const QStringList groups = m_settings->childGroups();
|
||||
for (const QString &g : groups) {
|
||||
if (!g.startsWith(QStringLiteral("servers/"))) continue;
|
||||
const QString label = g.mid(8);
|
||||
const QString label = g.mid(8); // length of "servers/"
|
||||
m_settings->beginGroup(g);
|
||||
SavedServer s;
|
||||
s.label = label;
|
||||
s.url = QUrl(m_settings->value(QStringLiteral("url")).toString());
|
||||
s.username = m_settings->value(QStringLiteral("username")).toString();
|
||||
s.password = m_settings->value(QStringLiteral("password")).toString());
|
||||
s.password = m_settings->value(QStringLiteral("password")).toString();
|
||||
m_settings->endGroup();
|
||||
list << s;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue