fixed changes

This commit is contained in:
dranik
2026-04-30 16:53:17 +03:00
parent 28709072bf
commit 4b1a0c0788
5 changed files with 113 additions and 74 deletions

View File

@@ -1,29 +1,28 @@
#include "xrayConfigurator.h"
#include "logger.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QUuid>
#include "logger.h"
#include "core/models/containerConfig.h"
#include "core/models/protocolConfig.h"
#include "core/models/protocols/xrayProtocolConfig.h"
#include "core/protocols/protocolUtils.h"
#include "core/utils/constants/configKeys.h"
#include "core/utils/constants/protocolConstants.h"
#include "core/utils/containerEnum.h"
#include "core/utils/containers/containerUtils.h"
#include "core/utils/protocolEnum.h"
#include "core/utils/selfhosted/scriptsRegistry.h"
#include "core/utils/selfhosted/sshSession.h"
#include "core/utils/selfhosted/scriptsRegistry.h"
#include "core/utils/protocolEnum.h"
#include "core/protocols/protocolUtils.h"
#include "core/utils/constants/configKeys.h"
#include "core/utils/constants/protocolConstants.h"
#include "core/models/containerConfig.h"
#include "core/models/protocols/xrayProtocolConfig.h"
namespace
{
namespace {
Logger logger("XrayConfigurator");
QString normalizeXhttpMode(const QString &m)
{
QString normalizeXhttpMode(const QString &m) {
const QString t = m.trimmed();
if (t.isEmpty() || t.compare(QLatin1String("Auto"), Qt::CaseInsensitive) == 0) {
return QStringLiteral("auto");
@@ -416,9 +415,9 @@ QJsonObject XrayConfigurator::buildStreamSettings(const XrayServerConfig &srv, c
}
ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const ContainerConfig &containerConfig,
const DnsSettings &dnsSettings,
ErrorCode &errorCode)
const ContainerConfig &containerConfig,
const DnsSettings &dnsSettings,
ErrorCode &errorCode)
{
const XrayServerConfig *serverConfig = nullptr;
if (const auto *xrayCfg = containerConfig.protocolConfig.as<XrayProtocolConfig>()) {
@@ -428,7 +427,7 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia
if (!serverConfig) {
logger.error() << "No XrayProtocolConfig found";
errorCode = ErrorCode::InternalError;
return XrayProtocolConfig {};
return XrayProtocolConfig{};
}
const XrayServerConfig &srv = *serverConfig;
@@ -436,7 +435,10 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia
QString xrayClientId = prepareServerConfig(credentials, container, containerConfig, dnsSettings, errorCode);
if (errorCode != ErrorCode::NoError || xrayClientId.isEmpty()) {
logger.error() << "Failed to prepare server config";
return XrayProtocolConfig {};
if (errorCode == ErrorCode::NoError) {
errorCode = ErrorCode::InternalError;
}
return XrayProtocolConfig{};
}
// Fetch server keys (Reality only)
@@ -448,7 +450,10 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia
amnezia::protocols::xray::PublicKeyPath, errorCode);
if (errorCode != ErrorCode::NoError || xrayPublicKey.isEmpty()) {
logger.error() << "Failed to get public key";
return XrayProtocolConfig {};
if (errorCode == ErrorCode::NoError) {
errorCode = ErrorCode::InternalError;
}
return XrayProtocolConfig{};
}
xrayPublicKey.replace("\n", "");
@@ -456,7 +461,10 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia
amnezia::protocols::xray::shortidPath, errorCode);
if (errorCode != ErrorCode::NoError || xrayShortId.isEmpty()) {
logger.error() << "Failed to get short ID";
return XrayProtocolConfig {};
if (errorCode == ErrorCode::NoError) {
errorCode = ErrorCode::InternalError;
}
return XrayProtocolConfig{};
}
xrayShortId.replace("\n", "");
}
@@ -522,4 +530,4 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia
protocolConfig.setClientConfig(clientConfig);
return protocolConfig;
}
}

View File

@@ -170,23 +170,46 @@ QJsonObject XrayServerConfig::toJson() const
QJsonObject obj;
// Existing fields
if (!port.isEmpty()) obj[configKey::port] = port;
if (!transportProto.isEmpty()) obj[configKey::transportProto] = transportProto;
if (!subnetAddress.isEmpty()) obj[configKey::subnetAddress] = subnetAddress;
if (!site.isEmpty()) obj[configKey::site] = site;
if (isThirdPartyConfig) obj[configKey::isThirdPartyConfig] = isThirdPartyConfig;
if (!port.isEmpty()) {
obj[configKey::port] = port;
}
if (!transportProto.isEmpty()) {
obj[configKey::transportProto] = transportProto;
}
if (!subnetAddress.isEmpty()) {
obj[configKey::subnetAddress] = subnetAddress;
}
if (!site.isEmpty()) {
obj[configKey::site] = site;
}
if (isThirdPartyConfig) {
obj[configKey::isThirdPartyConfig] = isThirdPartyConfig;
}
// New: Security
if (!security.isEmpty()) obj[configKey::xraySecurity] = security;
if (!flow.isEmpty()) obj[configKey::xrayFlow] = flow;
if (!fingerprint.isEmpty()) obj[configKey::xrayFingerprint] = fingerprint;
if (!sni.isEmpty()) obj[configKey::xraySni] = sni;
if (!alpn.isEmpty()) obj[configKey::xrayAlpn] = alpn;
if (!security.isEmpty()) {
obj[configKey::xraySecurity] = security;
}
if (!flow.isEmpty()) {
obj[configKey::xrayFlow] = flow;
}
if (!fingerprint.isEmpty()) {
obj[configKey::xrayFingerprint] = fingerprint;
}
if (!sni.isEmpty()) {
obj[configKey::xraySni] = sni;
}
if (!alpn.isEmpty()) {
obj[configKey::xrayAlpn] = alpn;
}
// New: Transport
if (!transport.isEmpty()) obj[configKey::xrayTransport] = transport;
if (!transport.isEmpty()) {
obj[configKey::xrayTransport] = transport;
}
obj["xhttp"] = xhttp.toJson();
obj["mkcp"] = mkcp.toJson();
obj["mkcp"] = mkcp.toJson();
return obj;
}
@@ -196,39 +219,39 @@ XrayServerConfig XrayServerConfig::fromJson(const QJsonObject &json)
XrayServerConfig c;
// Existing fields
c.port = json.value(configKey::port).toString();
c.transportProto = json.value(configKey::transportProto).toString();
c.subnetAddress = json.value(configKey::subnetAddress).toString();
c.site = json.value(configKey::site).toString();
c.port = json.value(configKey::port).toString();
c.transportProto = json.value(configKey::transportProto).toString();
c.subnetAddress = json.value(configKey::subnetAddress).toString();
c.site = json.value(configKey::site).toString();
c.isThirdPartyConfig = json.value(configKey::isThirdPartyConfig).toBool(false);
// New: Security
c.security = json.value(configKey::xraySecurity).toString(protocols::xray::defaultSecurity);
c.flow = json.value(configKey::xrayFlow).toString(protocols::xray::defaultFlow);
c.security = json.value(configKey::xraySecurity).toString(protocols::xray::defaultSecurity);
c.flow = json.value(configKey::xrayFlow).toString(protocols::xray::defaultFlow);
c.fingerprint = json.value(configKey::xrayFingerprint).toString(protocols::xray::defaultFingerprint);
if (c.fingerprint.contains(QLatin1String("Mozilla/5.0"), Qt::CaseInsensitive)) {
c.fingerprint = QString::fromLatin1(protocols::xray::defaultFingerprint);
}
c.sni = json.value(configKey::xraySni).toString(protocols::xray::defaultSni);
c.alpn = json.value(configKey::xrayAlpn).toString(protocols::xray::defaultAlpn);
c.sni = json.value(configKey::xraySni).toString(protocols::xray::defaultSni);
c.alpn = json.value(configKey::xrayAlpn).toString(protocols::xray::defaultAlpn);
// New: Transport
c.transport = json.value(configKey::xrayTransport).toString(protocols::xray::defaultTransport);
c.xhttp = XrayXhttpConfig::fromJson(json.value("xhttp").toObject());
c.mkcp = XrayMkcpConfig::fromJson(json.value("mkcp").toObject());
c.xhttp = XrayXhttpConfig::fromJson(json.value("xhttp").toObject());
c.mkcp = XrayMkcpConfig::fromJson(json.value("mkcp").toObject());
return c;
}
bool XrayServerConfig::hasEqualServerSettings(const XrayServerConfig &other) const
{
return port == other.port
&& site == other.site
&& security == other.security
&& flow == other.flow
&& transport == other.transport
&& fingerprint == other.fingerprint
&& sni == other.sni;
return port == other.port
&& site == other.site
&& security == other.security
&& flow == other.flow
&& transport == other.transport
&& fingerprint == other.fingerprint
&& sni == other.sni;
}
QJsonObject XrayClientConfig::toJson() const

View File

@@ -93,26 +93,26 @@ struct XrayMkcpConfig {
// ── Server config (settings editable by user) ─────────────────────────────────
struct XrayServerConfig {
// Existing fields
QString port;
QString transportProto;
QString subnetAddress;
QString site;
bool isThirdPartyConfig = false;
bool isThirdPartyConfig = false;
// New: Security
QString security = protocols::xray::defaultSecurity;
QString flow = protocols::xray::defaultFlow;
QString security = protocols::xray::defaultSecurity;
QString flow = protocols::xray::defaultFlow;
QString fingerprint = protocols::xray::defaultFingerprint;
QString sni = protocols::xray::defaultSni;
QString alpn = protocols::xray::defaultAlpn;
QString sni = protocols::xray::defaultSni;
QString alpn = protocols::xray::defaultAlpn;
// New: Transport
QString transport = protocols::xray::defaultTransport;
XrayXhttpConfig xhttp;
XrayMkcpConfig mkcp;
XrayMkcpConfig mkcp;
QJsonObject toJson() const;
static XrayServerConfig fromJson(const QJsonObject &json);
bool hasEqualServerSettings(const XrayServerConfig &other) const;
@@ -130,7 +130,7 @@ struct XrayClientConfig {
// ── Top-level protocol config ──────────────────────────────────────────────────
struct XrayProtocolConfig {
XrayServerConfig serverConfig;
XrayServerConfig serverConfig;
std::optional<XrayClientConfig> clientConfig;
QJsonObject toJson() const;

View File

@@ -167,8 +167,7 @@ bool XrayConfigModel::setData(const QModelIndex& index, const QVariant& value, i
QVariant XrayConfigModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount())
{
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
return QVariant();
}
@@ -252,14 +251,18 @@ QVariant XrayConfigModel::data(const QModelIndex& index, int role) const
return QVariant();
}
void XrayConfigModel::updateModel(amnezia::DockerContainer container,
const amnezia::XrayProtocolConfig& protocolConfig)
void XrayConfigModel::updateModel(amnezia::DockerContainer container, const amnezia::XrayProtocolConfig& protocolConfig)
{
beginResetModel();
m_container = container;
m_protocolConfig = protocolConfig;
applyDefaultsToServerConfig(m_protocolConfig.serverConfig);
m_originalProtocolConfig = m_protocolConfig;
endResetModel();
}
@@ -269,6 +272,11 @@ void XrayConfigModel::applyDefaultsToServerConfig(amnezia::XrayServerConfig &con
config.port = protocols::xray::defaultPort;
}
if (config.transportProto.isEmpty()) {
config.transportProto = ProtocolUtils::transportProtoToString(
ProtocolUtils::defaultTransportProto(amnezia::Proto::Xray), amnezia::Proto::Xray);
}
if (config.site.isEmpty()) {
config.site = protocols::xray::defaultSite;
}

View File

@@ -46,7 +46,7 @@ PageType {
delegate: ColumnLayout {
width: listView.width
property alias focusItemId: portTextField.textField
property alias focusItemId: textFieldWithHeaderType.textField
spacing: 0
@@ -87,7 +87,7 @@ PageType {
}
TextFieldWithHeaderType {
id: portTextField
id: textFieldWithHeaderType
Layout.fillWidth: true
Layout.topMargin: 32
Layout.leftMargin: 16
@@ -112,7 +112,7 @@ PageType {
descriptionText: transport
rightImageSource: "qrc:/images/controls/chevron-right.svg"
enabled: listView.enabled
clickedFunction: function () {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageProtocolXrayTransportSettings)
}
}
@@ -126,7 +126,7 @@ PageType {
descriptionText: security
rightImageSource: "qrc:/images/controls/chevron-right.svg"
enabled: listView.enabled
clickedFunction: function () {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageProtocolXraySecuritySettings)
}
}
@@ -140,7 +140,7 @@ PageType {
descriptionText: flow
rightImageSource: "qrc:/images/controls/chevron-right.svg"
enabled: listView.enabled
clickedFunction: function () {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageProtocolXrayFlowSettings)
}
}
@@ -158,15 +158,15 @@ PageType {
Layout.bottomMargin: 8
Layout.leftMargin: 16
Layout.rightMargin: 16
enabled: portTextField.errorText === ""
enabled: textFieldWithHeaderType.errorText === ""
text: qsTr("Save")
onClicked: function () {
onClicked: function() {
forceActiveFocus()
var headerText = qsTr("Save settings?")
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
var yesButtonText = qsTr("Continue")
var noButtonText = qsTr("Cancel")
var yesButtonFunction = function () {
var yesButtonFunction = function() {
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
return
@@ -174,7 +174,7 @@ PageType {
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
}
var noButtonFunction = function () {
var noButtonFunction = function() {
if (!GC.isMobile()) saveButton.forceActiveFocus()
}
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
@@ -188,12 +188,12 @@ PageType {
text: qsTr("Reset settings")
textColor: AmneziaStyle.color.vibrantRed
visible: listView.enabled
clickedFunction: function () {
var yesButtonFunction = function () {
clickedFunction: function() {
var yesButtonFunction = function() {
XrayConfigModel.resetToDefaults()
}
showQuestionDrawer(qsTr("Reset settings?"), qsTr("All XRay settings will be restored to defaults."),
qsTr("Reset"), qsTr("Cancel"), yesButtonFunction, function () {
qsTr("Reset"), qsTr("Cancel"), yesButtonFunction, function() {
})
}
}