mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
fix: various fixes for MTProxy & Telemt (#2653)
* fix color & fix enabled * fixed remove base secret * fix mtproxy/telemt 'base secret' * fixed button back * fixed loader * fixed reload loader * fixed dd secret * fixed qml * fix: fixed header link in mtproxy/telemt page --------- Co-authored-by: vkamn <vk@amnezia.org>
This commit is contained in:
@@ -119,9 +119,14 @@ ErrorCode InstallController::setupContainer(const ServerCredentials &credentials
|
|||||||
return e;
|
return e;
|
||||||
qDebug().noquote() << "InstallController::setupContainer prepareHostWorker finished";
|
qDebug().noquote() << "InstallController::setupContainer prepareHostWorker finished";
|
||||||
|
|
||||||
|
amnezia::ScriptVars removeContainerVars =
|
||||||
|
amnezia::genBaseVars(credentials, container, QString(), QString());
|
||||||
|
if (!isUpdate) {
|
||||||
|
removeContainerVars.append({ { "$REMOVE_CONTAINER_DATA", QStringLiteral("1") } });
|
||||||
|
}
|
||||||
sshSession.runScript(credentials,
|
sshSession.runScript(credentials,
|
||||||
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
|
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
|
||||||
amnezia::genBaseVars(credentials, container, QString(), QString())));
|
removeContainerVars));
|
||||||
qDebug().noquote() << "InstallController::setupContainer removeContainer finished";
|
qDebug().noquote() << "InstallController::setupContainer removeContainer finished";
|
||||||
|
|
||||||
qDebug().noquote() << "buildContainerWorker start";
|
qDebug().noquote() << "buildContainerWorker start";
|
||||||
@@ -942,10 +947,12 @@ ErrorCode InstallController::removeContainer(const QString &serverId, DockerCont
|
|||||||
return ErrorCode::InternalError;
|
return ErrorCode::InternalError;
|
||||||
}
|
}
|
||||||
SshSession sshSession(this);
|
SshSession sshSession(this);
|
||||||
|
amnezia::ScriptVars removeContainerVars =
|
||||||
|
amnezia::genBaseVars(credentials, container, QString(), QString());
|
||||||
|
removeContainerVars.append({ { "$REMOVE_CONTAINER_DATA", QStringLiteral("1") } });
|
||||||
ErrorCode errorCode = sshSession.runScript(
|
ErrorCode errorCode = sshSession.runScript(
|
||||||
credentials,
|
credentials,
|
||||||
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
|
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container), removeContainerVars));
|
||||||
amnezia::genBaseVars(credentials, container, QString(), QString())));
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
QMap<DockerContainer, ContainerConfig> containers = adminConfig->containers;
|
QMap<DockerContainer, ContainerConfig> containers = adminConfig->containers;
|
||||||
|
|||||||
@@ -295,6 +295,8 @@ amnezia::ScriptVars amnezia::genMtProxyVars(const ContainerConfig &containerConf
|
|||||||
|
|
||||||
vars.append({{"$MTPROXY_PORT", c.port.isEmpty() ? QString(protocols::mtProxy::defaultPort) : c.port}});
|
vars.append({{"$MTPROXY_PORT", c.port.isEmpty() ? QString(protocols::mtProxy::defaultPort) : c.port}});
|
||||||
vars.append({{"$MTPROXY_SECRET", c.secret}});
|
vars.append({{"$MTPROXY_SECRET", c.secret}});
|
||||||
|
vars.append({{"$MTPROXY_REGENERATE_SECRET",
|
||||||
|
c.secret.isEmpty() ? QStringLiteral("1") : QStringLiteral("0")}});
|
||||||
vars.append({{"$MTPROXY_TAG", c.tag}});
|
vars.append({{"$MTPROXY_TAG", c.tag}});
|
||||||
vars.append({{"$MTPROXY_TRANSPORT_MODE",
|
vars.append({{"$MTPROXY_TRANSPORT_MODE",
|
||||||
c.transportMode.isEmpty() ? QString(protocols::mtProxy::transportModeStandard)
|
c.transportMode.isEmpty() ? QString(protocols::mtProxy::transportModeStandard)
|
||||||
@@ -350,6 +352,8 @@ amnezia::ScriptVars amnezia::genTelemtVars(const ContainerConfig &containerConfi
|
|||||||
vars.append({ { "$TELEMT_TOML_TLS", faketls ? QLatin1String("true") : QLatin1String("false") } });
|
vars.append({ { "$TELEMT_TOML_TLS", faketls ? QLatin1String("true") : QLatin1String("false") } });
|
||||||
vars.append({ { "$TELEMT_PORT", c.port.isEmpty() ? QString(protocols::telemt::defaultPort) : c.port } });
|
vars.append({ { "$TELEMT_PORT", c.port.isEmpty() ? QString(protocols::telemt::defaultPort) : c.port } });
|
||||||
vars.append({ { "$TELEMT_SECRET", c.secret } });
|
vars.append({ { "$TELEMT_SECRET", c.secret } });
|
||||||
|
vars.append({ { "$TELEMT_REGENERATE_SECRET",
|
||||||
|
c.secret.isEmpty() ? QStringLiteral("1") : QStringLiteral("0") } });
|
||||||
vars.append({ { "$TELEMT_TAG", c.tag } });
|
vars.append({ { "$TELEMT_TAG", c.tag } });
|
||||||
QString tlsDomain = c.tlsDomain;
|
QString tlsDomain = c.tlsDomain;
|
||||||
if (tlsDomain.isEmpty()) {
|
if (tlsDomain.isEmpty()) {
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
curl -s https://core.telegram.org/getProxySecret -o /data/proxy-secret
|
curl -s https://core.telegram.org/getProxySecret -o /data/proxy-secret
|
||||||
curl -s https://core.telegram.org/getProxyConfig -o /data/proxy-multi.conf
|
curl -s https://core.telegram.org/getProxyConfig -o /data/proxy-multi.conf
|
||||||
|
|
||||||
# Determine secret: env var -> saved file -> generate new
|
# Determine secret: regenerate (fresh install) -> env var -> saved file -> generate new
|
||||||
if [ -n "$MTPROXY_SECRET" ]; then
|
if [ "$MTPROXY_REGENERATE_SECRET" = "1" ]; then
|
||||||
|
SECRET=$(openssl rand -hex 16)
|
||||||
|
elif [ -n "$MTPROXY_SECRET" ]; then
|
||||||
SECRET="$MTPROXY_SECRET"
|
SECRET="$MTPROXY_SECRET"
|
||||||
elif [ -f /data/secret ]; then
|
elif [ -f /data/secret ]; then
|
||||||
SECRET=$(cat /data/secret)
|
SECRET=$(cat /data/secret)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
sudo docker stop $CONTAINER_NAME;\
|
sudo docker stop $CONTAINER_NAME;\
|
||||||
sudo docker rm -fv $CONTAINER_NAME;\
|
sudo docker rm -fv $CONTAINER_NAME;\
|
||||||
sudo docker rmi $CONTAINER_NAME
|
sudo docker rmi $CONTAINER_NAME;\
|
||||||
|
test "$REMOVE_CONTAINER_DATA" = "1" && sudo docker volume rm -f ${CONTAINER_NAME}-data 2>/dev/null || true
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
echo "[*] Amnezia Telemt: configure script start"
|
echo "[*] Amnezia Telemt: configure script start"
|
||||||
mkdir -p /data/tlsfront
|
mkdir -p /data/tlsfront
|
||||||
|
|
||||||
# Secret: substituted $TELEMT_SECRET -> saved file -> openssl (same rules as MTProxy configure)
|
# Secret: regenerate (fresh install) -> env var -> saved file -> openssl
|
||||||
if [ -n "$TELEMT_SECRET" ]; then
|
if [ "$TELEMT_REGENERATE_SECRET" = "1" ]; then
|
||||||
|
SECRET=$(openssl rand -hex 16)
|
||||||
|
elif [ -n "$TELEMT_SECRET" ]; then
|
||||||
SECRET="$TELEMT_SECRET"
|
SECRET="$TELEMT_SECRET"
|
||||||
elif [ -f /data/secret ]; then
|
elif [ -f /data/secret ]; then
|
||||||
SECRET=$(cat /data/secret)
|
SECRET=$(cat /data/secret)
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ ListViewType {
|
|||||||
PageController.goToPage(PageEnum.PageServiceDnsSettings)
|
PageController.goToPage(PageEnum.PageServiceDnsSettings)
|
||||||
} else if (isMtProxy) {
|
} else if (isMtProxy) {
|
||||||
MtProxyConfigModel.updateModel(config)
|
MtProxyConfigModel.updateModel(config)
|
||||||
PageController.goToPage(PageEnum.PageServiceMtProxySettings)
|
PageController.goToPage(PageEnum.PageServiceMtProxySettings, false)
|
||||||
} else if (isTelemt) {
|
} else if (isTelemt) {
|
||||||
TelemtConfigModel.updateModel(config)
|
TelemtConfigModel.updateModel(config)
|
||||||
PageController.goToPage(PageEnum.PageServiceTelemtSettings)
|
PageController.goToPage(PageEnum.PageServiceTelemtSettings, false)
|
||||||
} else {
|
} else {
|
||||||
InstallController.updateProtocols(ServersUiController.processedServerId, containerIndex)
|
InstallController.updateProtocols(ServersUiController.processedServerId, containerIndex)
|
||||||
PageController.goToPage(PageEnum.PageSettingsServerProtocol)
|
PageController.goToPage(PageEnum.PageSettingsServerProtocol)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ Item {
|
|||||||
property int headerTextMaximumLineCount: 2
|
property int headerTextMaximumLineCount: 2
|
||||||
property int headerTextElide: Qt.ElideRight
|
property int headerTextElide: Qt.ElideRight
|
||||||
property string descriptionText
|
property string descriptionText
|
||||||
|
property string descriptionLinkText
|
||||||
|
property string descriptionLinkUrl
|
||||||
property alias headerRow: headerRow
|
property alias headerRow: headerRow
|
||||||
|
|
||||||
implicitWidth: content.implicitWidth
|
implicitWidth: content.implicitWidth
|
||||||
@@ -43,5 +45,26 @@ Item {
|
|||||||
color: AmneziaStyle.color.mutedGray
|
color: AmneziaStyle.color.mutedGray
|
||||||
visible: root.descriptionText !== ""
|
visible: root.descriptionText !== ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
id: descriptionLink
|
||||||
|
Layout.topMargin: 16
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: root.descriptionLinkText !== "" && root.descriptionLinkUrl !== ""
|
||||||
|
? ("<a href=\"" + root.descriptionLinkUrl + "\" style=\"color: " + AmneziaStyle.color.goldenApricotString + ";\">" + root.descriptionLinkText + "</a>")
|
||||||
|
: ""
|
||||||
|
textFormat: Text.RichText
|
||||||
|
visible: root.descriptionLinkText !== ""
|
||||||
|
|
||||||
|
onLinkActivated: function(link) {
|
||||||
|
Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,15 +20,10 @@ import "../Components"
|
|||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
z: -1
|
|
||||||
color: AmneziaStyle.color.onyxBlack
|
|
||||||
}
|
|
||||||
|
|
||||||
property int containerStatus: 1
|
property int containerStatus: 1
|
||||||
property bool isUpdating: false
|
property bool isUpdating: false
|
||||||
property bool isCheckingStatus: false
|
property bool isCheckingStatus: false
|
||||||
|
property bool isFetchingSecret: false
|
||||||
property bool previousEnabled: true
|
property bool previousEnabled: true
|
||||||
property int previousContainerStatus: 1
|
property int previousContainerStatus: 1
|
||||||
|
|
||||||
@@ -50,7 +45,7 @@ PageType {
|
|||||||
|
|
||||||
onSavedTransportModeChanged: {
|
onSavedTransportModeChanged: {
|
||||||
if (savedTransportMode === "faketls") {
|
if (savedTransportMode === "faketls") {
|
||||||
root.syncedSecretTabIndex = 2
|
root.syncedSecretTabIndex = 1
|
||||||
} else if (savedTransportMode !== "") {
|
} else if (savedTransportMode !== "") {
|
||||||
root.syncedSecretTabIndex = 0
|
root.syncedSecretTabIndex = 0
|
||||||
}
|
}
|
||||||
@@ -68,9 +63,96 @@ PageType {
|
|||||||
|
|
||||||
readonly property bool mtProxyNetworkBlocked: !NetworkReachabilityController.hasInternetAccess
|
readonly property bool mtProxyNetworkBlocked: !NetworkReachabilityController.hasInternetAccess
|
||||||
|
|
||||||
readonly property bool navigationBlockedWhileBusy: isUpdating || diagLoading
|
property bool remoteOperationBusy: false
|
||||||
|
readonly property bool operationInProgress: isCheckingStatus || isFetchingSecret || isUpdating || diagLoading
|
||||||
|
readonly property bool pageBusy: operationInProgress || remoteOperationBusy
|
||||||
|
readonly property bool navigationBlockedWhileBusy: pageBusy
|
||||||
|
|
||||||
|
property bool pageOpenHandled: false
|
||||||
|
property bool busyIndicatorShown: false
|
||||||
|
|
||||||
|
function syncPageBusyIndicator() {
|
||||||
|
if (!root.pageOpenHandled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var wantBusy = root.pageBusy
|
||||||
|
if (wantBusy === root.busyIndicatorShown) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
root.busyIndicatorShown = wantBusy
|
||||||
|
PageController.showBusyIndicator(wantBusy)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPageBusyChanged: syncPageBusyIndicator()
|
||||||
|
|
||||||
|
function mtProxyDomainToHex(domain) {
|
||||||
|
var hex = ""
|
||||||
|
for (var i = 0; i < domain.length; i++) {
|
||||||
|
var code = domain.charCodeAt(i).toString(16)
|
||||||
|
hex += (code.length < 2 ? "0" : "") + code
|
||||||
|
}
|
||||||
|
return hex
|
||||||
|
}
|
||||||
|
|
||||||
|
function mtProxyClientSecret(baseHex32, mode, tlsDomain) {
|
||||||
|
if (baseHex32 === "") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if (mode === "faketls") {
|
||||||
|
return "ee" + baseHex32 + mtProxyDomainToHex(tlsDomain)
|
||||||
|
}
|
||||||
|
return "dd" + baseHex32
|
||||||
|
}
|
||||||
|
|
||||||
|
function mtProxyClientSecretForTabIndex(baseHex32, tabIndex, tlsDomain, defaultTlsDomain) {
|
||||||
|
var domain = tlsDomain !== "" ? tlsDomain : defaultTlsDomain
|
||||||
|
if (tabIndex === 1) {
|
||||||
|
return mtProxyClientSecret(baseHex32, "faketls", domain)
|
||||||
|
}
|
||||||
|
return mtProxyClientSecret(baseHex32, "standard", domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool containerStatusRefreshCallPending: false
|
||||||
|
|
||||||
|
function mtProxyRequestContainerStatusRefresh() {
|
||||||
|
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||||
|
isCheckingStatus = false
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isCheckingStatus = true
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
function mtProxyScheduleContainerStatusRefresh() {
|
||||||
|
if (containerStatusRefreshCallPending) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
containerStatusRefreshCallPending = true
|
||||||
|
Qt.callLater(function () {
|
||||||
|
containerStatusRefreshCallPending = false
|
||||||
|
root.mtProxyRequestContainerStatusRefresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function mtProxyOnPageShown() {
|
||||||
|
if (root.pageOpenHandled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
root.pageOpenHandled = true
|
||||||
|
|
||||||
|
PageController.disableControls(navigationBlockedWhileBusy)
|
||||||
|
|
||||||
|
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||||
|
isCheckingStatus = false
|
||||||
|
} else {
|
||||||
|
isCheckingStatus = true
|
||||||
|
}
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
root.mtProxyScheduleContainerStatusRefresh()
|
||||||
|
}
|
||||||
|
|
||||||
// Hex values that exist in last loaded / last successfully saved config — show link panel only for these.
|
|
||||||
property var mtProxyPersistedAdditionalHex: []
|
property var mtProxyPersistedAdditionalHex: []
|
||||||
|
|
||||||
function mtProxyRefreshPersistedAdditionalSecrets() {
|
function mtProxyRefreshPersistedAdditionalSecrets() {
|
||||||
@@ -92,11 +174,8 @@ PageType {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rejects garbage like "123123123123"; only dotted IPv4 shape (≤3 digits per octet, ≤4 octets).
|
|
||||||
readonly property var natIpv4InputFormat: /^(\d{1,3}\.){0,3}\d{0,3}$/
|
readonly property var natIpv4InputFormat: /^(\d{1,3}\.){0,3}\d{0,3}$/
|
||||||
|
|
||||||
// Defer SSH/updateContainer so QML control handlers return before nested event loops run;
|
|
||||||
// avoids "Object destroyed while one of its QML signal handlers is in progress".
|
|
||||||
function mtProxyScheduleUpdate(closePage) {
|
function mtProxyScheduleUpdate(closePage) {
|
||||||
var cp = closePage === undefined ? false : closePage
|
var cp = closePage === undefined ? false : closePage
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
@@ -104,7 +183,6 @@ PageType {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional IPv4: show invalid while typing only when the string looks complete (four octets), so partial entry is not nagged.
|
|
||||||
function natIpv4FieldShowInvalidError(text) {
|
function natIpv4FieldShowInvalidError(text) {
|
||||||
var t = text ? String(text).replace(/^\s+|\s+$/g, '') : ""
|
var t = text ? String(text).replace(/^\s+|\s+$/g, '') : ""
|
||||||
if (t === "")
|
if (t === "")
|
||||||
@@ -167,15 +245,9 @@ PageType {
|
|||||||
root.mtProxyRefreshPersistedAdditionalSecrets()
|
root.mtProxyRefreshPersistedAdditionalSecrets()
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
Qt.callLater(root.mtProxyOnPageShown)
|
||||||
isCheckingStatus = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
isCheckingStatus = true
|
|
||||||
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block back navigation and Escape (via PageStart.isControlsDisabled) while SSH/update or diagnostics refresh runs.
|
|
||||||
onNavigationBlockedWhileBusyChanged: {
|
onNavigationBlockedWhileBusyChanged: {
|
||||||
if (root.visible) {
|
if (root.visible) {
|
||||||
PageController.disableControls(navigationBlockedWhileBusy)
|
PageController.disableControls(navigationBlockedWhileBusy)
|
||||||
@@ -184,10 +256,16 @@ PageType {
|
|||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
|
root.pageOpenHandled = false
|
||||||
|
containerStatusRefreshCallPending = false
|
||||||
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
|
busyIndicatorShown = false
|
||||||
PageController.disableControls(false)
|
PageController.disableControls(false)
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
diagLoading = false
|
diagLoading = false
|
||||||
} else {
|
} else {
|
||||||
PageController.disableControls(navigationBlockedWhileBusy)
|
root.mtProxyOnPageShown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,8 +277,7 @@ PageType {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (NetworkReachabilityController.hasInternetAccess) {
|
if (NetworkReachabilityController.hasInternetAccess) {
|
||||||
isCheckingStatus = true
|
root.mtProxyScheduleContainerStatusRefresh()
|
||||||
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,10 +285,15 @@ PageType {
|
|||||||
Connections {
|
Connections {
|
||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
|
function onServerIsBusy(busy) {
|
||||||
|
remoteOperationBusy = busy
|
||||||
|
}
|
||||||
|
|
||||||
function onUpdateContainerFinished(message, closePage) {
|
function onUpdateContainerFinished(message, closePage) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
isCheckingStatus = false
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
@@ -227,9 +309,11 @@ PageType {
|
|||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
isCheckingStatus = false
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
|
isFetchingSecret = false
|
||||||
containerStatus = previousContainerStatus
|
containerStatus = previousContainerStatus
|
||||||
MtProxyConfigModel.setEnabled(previousEnabled)
|
MtProxyConfigModel.setEnabled(previousEnabled)
|
||||||
MtProxyConfigModel.setPort(previousPort)
|
MtProxyConfigModel.setPort(previousPort)
|
||||||
@@ -254,6 +338,7 @@ PageType {
|
|||||||
}
|
}
|
||||||
if (enabled && pendingUpdateAfterEnable) {
|
if (enabled && pendingUpdateAfterEnable) {
|
||||||
pendingUpdateAfterEnable = false
|
pendingUpdateAfterEnable = false
|
||||||
|
isUpdating = true
|
||||||
root.mtProxyScheduleUpdate(false)
|
root.mtProxyScheduleUpdate(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -266,9 +351,9 @@ PageType {
|
|||||||
function onContainerStatusRefreshed(status) {
|
function onContainerStatusRefreshed(status) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
isCheckingStatus = false
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isCheckingStatus = false
|
|
||||||
containerStatus = status
|
containerStatus = status
|
||||||
|
|
||||||
root.savedTransportMode = MtProxyConfigModel.getTransportMode()
|
root.savedTransportMode = MtProxyConfigModel.getTransportMode()
|
||||||
@@ -276,11 +361,18 @@ PageType {
|
|||||||
root.savedPublicHost = MtProxyConfigModel.getPublicHost()
|
root.savedPublicHost = MtProxyConfigModel.getPublicHost()
|
||||||
if (status === 1) {
|
if (status === 1) {
|
||||||
MtProxyConfigModel.setEnabled(true)
|
MtProxyConfigModel.setEnabled(true)
|
||||||
|
isFetchingSecret = true
|
||||||
|
isCheckingStatus = false
|
||||||
InstallController.fetchContainerSecret(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
InstallController.fetchContainerSecret(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||||
} else if (status === 2) {
|
} else {
|
||||||
|
isFetchingSecret = false
|
||||||
|
isCheckingStatus = false
|
||||||
|
if (status === 2) {
|
||||||
MtProxyConfigModel.setEnabled(false)
|
MtProxyConfigModel.setEnabled(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
}
|
||||||
|
|
||||||
function onContainerDiagnosticsRefreshed(portReachable, upstreamReachable, clientsConnected, lastConfigRefresh, statsEndpoint) {
|
function onContainerDiagnosticsRefreshed(portReachable, upstreamReachable, clientsConnected, lastConfigRefresh, statsEndpoint) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
@@ -296,20 +388,35 @@ PageType {
|
|||||||
|
|
||||||
function onContainerSecretFetched(secret) {
|
function onContainerSecretFetched(secret) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
isFetchingSecret = false
|
||||||
|
syncPageBusyIndicator()
|
||||||
MtProxyConfigModel.validateAndSetSecret(secret)
|
MtProxyConfigModel.validateAndSetSecret(secret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: contentLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: !root.pageBusy
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20 + SettingsController.safeAreaTopMargin
|
anchors.topMargin: 20 + PageController.safeAreaTopMargin
|
||||||
|
|
||||||
onFocusChanged: {
|
onFocusChanged: {
|
||||||
if (this.activeFocus) connectionListView.positionViewAtBeginning()
|
if (this.activeFocus) {
|
||||||
|
if (mainTabBar.currentIndex === 0) {
|
||||||
|
connectionListView.positionViewAtBeginning()
|
||||||
|
} else {
|
||||||
|
settingsListView.positionViewAtBeginning()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,32 +425,38 @@ PageType {
|
|||||||
anchors.top: backButton.bottom
|
anchors.top: backButton.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 8
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
BaseHeaderType {
|
BaseHeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.topMargin: 8
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
headerText: qsTr("MTProxy settings")
|
headerText: qsTr("MTProxy settings")
|
||||||
|
descriptionLinkText: qsTr("Read more about this settings")
|
||||||
|
descriptionLinkUrl: "https://core.telegram.org/proxy"
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
CaptionTextType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 0
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
text: qsTr("Read more about this settings")
|
Layout.topMargin: 8
|
||||||
textColor: AmneziaStyle.color.goldenApricot
|
visible: root.mtProxyNetworkBlocked
|
||||||
clickedFunction: function () {
|
text: qsTr("No internet connection. Connect to the internet to change MTProxy settings.")
|
||||||
Qt.openUrlExternally("https://core.telegram.org/proxy")
|
color: AmneziaStyle.color.mutedGray
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
font.pixelSize: 14
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TabBar {
|
TabBar {
|
||||||
id: mainTabBar
|
id: mainTabBar
|
||||||
Layout.fillWidth: true
|
anchors.top: pageHeader.bottom
|
||||||
Layout.topMargin: 4
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: AmneziaStyle.color.transparent
|
color: AmneziaStyle.color.transparent
|
||||||
@@ -364,11 +477,10 @@ PageType {
|
|||||||
isSelected: mainTabBar.currentIndex === 1
|
isSelected: mainTabBar.currentIndex === 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
StackLayout {
|
StackLayout {
|
||||||
id: tabContent
|
id: tabContent
|
||||||
anchors.top: pageHeader.bottom
|
anchors.top: mainTabBar.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -382,35 +494,11 @@ PageType {
|
|||||||
width: connectionListView.width
|
width: connectionListView.width
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
function domainToHex(domain) {
|
|
||||||
var hex = ""
|
|
||||||
for (var i = 0; i < domain.length; i++) {
|
|
||||||
var code = domain.charCodeAt(i).toString(16)
|
|
||||||
hex += (code.length < 2 ? "0" : "") + code
|
|
||||||
}
|
|
||||||
return hex
|
|
||||||
}
|
|
||||||
|
|
||||||
function secretForMode(mode) {
|
|
||||||
if (mode === "faketls") {
|
|
||||||
var domain = root.savedTlsDomain !== "" ? root.savedTlsDomain : MtProxyConfigModel.defaultTlsDomain()
|
|
||||||
return "ee" + secret + domainToHex(domain)
|
|
||||||
} else if (mode === "padded") {
|
|
||||||
return "dd" + secret
|
|
||||||
}
|
|
||||||
return secret
|
|
||||||
}
|
|
||||||
|
|
||||||
property int secretTabIndex: root.syncedSecretTabIndex
|
property int secretTabIndex: root.syncedSecretTabIndex
|
||||||
|
|
||||||
function activeSecret() {
|
function activeSecret() {
|
||||||
if (root.syncedSecretTabIndex === 0) {
|
return root.mtProxyClientSecretForTabIndex(secret, root.syncedSecretTabIndex,
|
||||||
return secretForMode("standard")
|
root.savedTlsDomain, MtProxyConfigModel.defaultTlsDomain())
|
||||||
}
|
|
||||||
if (root.syncedSecretTabIndex === 1) {
|
|
||||||
return secretForMode("padded")
|
|
||||||
}
|
|
||||||
return secretForMode("faketls")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function effectiveSecret() {
|
function effectiveSecret() {
|
||||||
@@ -754,33 +842,9 @@ PageType {
|
|||||||
width: settingsListView.width
|
width: settingsListView.width
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
function mtProxyDomainToHex(domain) {
|
|
||||||
var hex = ""
|
|
||||||
for (var i = 0; i < domain.length; i++) {
|
|
||||||
var code = domain.charCodeAt(i).toString(16)
|
|
||||||
hex += (code.length < 2 ? "0" : "") + code
|
|
||||||
}
|
|
||||||
return hex
|
|
||||||
}
|
|
||||||
|
|
||||||
function mtProxySecretForBaseHex(baseHex, mode) {
|
|
||||||
if (mode === "faketls") {
|
|
||||||
var domain = root.savedTlsDomain !== "" ? root.savedTlsDomain : MtProxyConfigModel.defaultTlsDomain()
|
|
||||||
return "ee" + baseHex + mtProxyDomainToHex(domain)
|
|
||||||
} else if (mode === "padded") {
|
|
||||||
return "dd" + baseHex
|
|
||||||
}
|
|
||||||
return baseHex
|
|
||||||
}
|
|
||||||
|
|
||||||
function mtProxyActiveSecretForBaseHex(baseHex) {
|
function mtProxyActiveSecretForBaseHex(baseHex) {
|
||||||
if (root.syncedSecretTabIndex === 0) {
|
return root.mtProxyClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex,
|
||||||
return mtProxySecretForBaseHex(baseHex, "standard")
|
root.savedTlsDomain, MtProxyConfigModel.defaultTlsDomain())
|
||||||
}
|
|
||||||
if (root.syncedSecretTabIndex === 1) {
|
|
||||||
return mtProxySecretForBaseHex(baseHex, "padded")
|
|
||||||
}
|
|
||||||
return mtProxySecretForBaseHex(baseHex, "faketls")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mtProxyEffectiveHostForLinks() {
|
function mtProxyEffectiveHostForLinks() {
|
||||||
@@ -804,7 +868,7 @@ PageType {
|
|||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
text: qsTr("Enable MTProxy")
|
text: qsTr("Enable MTProxy")
|
||||||
checked: isEnabled
|
checked: isEnabled
|
||||||
enabled: !isCheckingStatus && containerStatus !== 0 && containerStatus !== 3 && !isUpdating
|
enabled: containerStatus !== 0 && containerStatus !== 3 && !root.pageBusy
|
||||||
&& !root.mtProxyNetworkBlocked
|
&& !root.mtProxyNetworkBlocked
|
||||||
onToggled: function () {
|
onToggled: function () {
|
||||||
if (checked !== isEnabled) {
|
if (checked !== isEnabled) {
|
||||||
@@ -843,13 +907,14 @@ PageType {
|
|||||||
|
|
||||||
CaptionTextType {
|
CaptionTextType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: secret !== "" ? secret : qsTr("Not generated")
|
text: secret !== "" ? mtProxyActiveSecretForBaseHex(secret) : qsTr("Not generated")
|
||||||
color: secret !== "" ? AmneziaStyle.color.paleGray : AmneziaStyle.color.mutedGray
|
color: secret !== "" ? AmneziaStyle.color.paleGray : AmneziaStyle.color.mutedGray
|
||||||
elide: Text.ElideMiddle
|
wrapMode: Text.WrapAnywhere
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
implicitWidth: 36
|
implicitWidth: 36
|
||||||
implicitHeight: 36
|
implicitHeight: 36
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
@@ -1098,6 +1163,7 @@ PageType {
|
|||||||
clickedFunction: function () {
|
clickedFunction: function () {
|
||||||
transportMode = (index === 0) ? "standard" : "faketls"
|
transportMode = (index === 0) ? "standard" : "faketls"
|
||||||
MtProxyConfigModel.setTransportMode(transportMode)
|
MtProxyConfigModel.setTransportMode(transportMode)
|
||||||
|
root.syncedSecretTabIndex = transportMode === "faketls" ? 1 : 0
|
||||||
transportModeDropDown.closeTriggered()
|
transportModeDropDown.closeTriggered()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1286,6 +1352,9 @@ PageType {
|
|||||||
imageColor: AmneziaStyle.color.vibrantRed
|
imageColor: AmneziaStyle.color.vibrantRed
|
||||||
onClicked: {
|
onClicked: {
|
||||||
MtProxyConfigModel.removeAdditionalSecret(index)
|
MtProxyConfigModel.removeAdditionalSecret(index)
|
||||||
|
if (containerStatus === 1) {
|
||||||
|
root.mtProxyScheduleUpdate(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1852,34 +1921,5 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
visible: isCheckingStatus || isUpdating || root.mtProxyNetworkBlocked
|
|
||||||
color: AmneziaStyle.color.midnightBlack
|
|
||||||
opacity: 0.6
|
|
||||||
z: 1
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
BusyIndicator {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: isCheckingStatus || isUpdating
|
|
||||||
running: isCheckingStatus || isUpdating
|
|
||||||
width: 48
|
|
||||||
height: 48
|
|
||||||
}
|
|
||||||
CaptionTextType {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.leftMargin: 24
|
|
||||||
anchors.rightMargin: 24
|
|
||||||
visible: root.mtProxyNetworkBlocked && !isCheckingStatus && !isUpdating
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("No internet connection. Connect to the internet to change MTProxy settings.")
|
|
||||||
color: AmneziaStyle.color.paleGray
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
font.pixelSize: 14
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,10 @@ import "../Components"
|
|||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
z: -1
|
|
||||||
color: AmneziaStyle.color.onyxBlack
|
|
||||||
}
|
|
||||||
|
|
||||||
property int containerStatus: 1
|
property int containerStatus: 1
|
||||||
property bool isUpdating: false
|
property bool isUpdating: false
|
||||||
property bool isCheckingStatus: false
|
property bool isCheckingStatus: false
|
||||||
|
property bool isFetchingSecret: false
|
||||||
property bool previousEnabled: true
|
property bool previousEnabled: true
|
||||||
property int previousContainerStatus: 1
|
property int previousContainerStatus: 1
|
||||||
|
|
||||||
@@ -40,6 +35,7 @@ PageType {
|
|||||||
property bool previousNatEnabled: false
|
property bool previousNatEnabled: false
|
||||||
property string previousNatInternalIp: ""
|
property string previousNatInternalIp: ""
|
||||||
property string previousNatExternalIp: ""
|
property string previousNatExternalIp: ""
|
||||||
|
property string previousSecret: ""
|
||||||
|
|
||||||
property string savedTransportMode: ""
|
property string savedTransportMode: ""
|
||||||
property string savedTlsDomain: ""
|
property string savedTlsDomain: ""
|
||||||
@@ -47,7 +43,7 @@ PageType {
|
|||||||
|
|
||||||
onSavedTransportModeChanged: {
|
onSavedTransportModeChanged: {
|
||||||
if (savedTransportMode === "faketls") {
|
if (savedTransportMode === "faketls") {
|
||||||
root.syncedSecretTabIndex = 2
|
root.syncedSecretTabIndex = 1
|
||||||
} else if (savedTransportMode !== "") {
|
} else if (savedTransportMode !== "") {
|
||||||
root.syncedSecretTabIndex = 0
|
root.syncedSecretTabIndex = 0
|
||||||
}
|
}
|
||||||
@@ -64,9 +60,97 @@ PageType {
|
|||||||
property string diagStatsEndpoint: ""
|
property string diagStatsEndpoint: ""
|
||||||
|
|
||||||
readonly property bool telemtNetworkBlocked: !NetworkReachabilityController.hasInternetAccess
|
readonly property bool telemtNetworkBlocked: !NetworkReachabilityController.hasInternetAccess
|
||||||
readonly property bool navigationBlockedWhileBusy: isUpdating || diagLoading
|
|
||||||
|
|
||||||
// Defer SSH/updateContainer so QML control handlers return before nested event loops run.
|
property bool remoteOperationBusy: false
|
||||||
|
readonly property bool operationInProgress: isCheckingStatus || isFetchingSecret || isUpdating || diagLoading
|
||||||
|
readonly property bool pageBusy: operationInProgress || remoteOperationBusy
|
||||||
|
readonly property bool navigationBlockedWhileBusy: pageBusy
|
||||||
|
|
||||||
|
property bool pageOpenHandled: false
|
||||||
|
property bool busyIndicatorShown: false
|
||||||
|
|
||||||
|
function syncPageBusyIndicator() {
|
||||||
|
if (!root.pageOpenHandled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var wantBusy = root.pageBusy
|
||||||
|
if (wantBusy === root.busyIndicatorShown) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
root.busyIndicatorShown = wantBusy
|
||||||
|
PageController.showBusyIndicator(wantBusy)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPageBusyChanged: syncPageBusyIndicator()
|
||||||
|
|
||||||
|
function telemtDomainToHex(domain) {
|
||||||
|
var hex = ""
|
||||||
|
for (var i = 0; i < domain.length; i++) {
|
||||||
|
var code = domain.charCodeAt(i).toString(16)
|
||||||
|
hex += (code.length < 2 ? "0" : "") + code
|
||||||
|
}
|
||||||
|
return hex
|
||||||
|
}
|
||||||
|
|
||||||
|
function telemtClientSecret(baseHex32, mode, tlsDomain) {
|
||||||
|
if (baseHex32 === "") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if (mode === "faketls") {
|
||||||
|
return "ee" + baseHex32 + telemtDomainToHex(tlsDomain)
|
||||||
|
}
|
||||||
|
return "dd" + baseHex32
|
||||||
|
}
|
||||||
|
|
||||||
|
function telemtClientSecretForTabIndex(baseHex32, tabIndex, tlsDomain, defaultTlsDomain) {
|
||||||
|
var domain = tlsDomain !== "" ? tlsDomain : defaultTlsDomain
|
||||||
|
if (tabIndex === 1) {
|
||||||
|
return telemtClientSecret(baseHex32, "faketls", domain)
|
||||||
|
}
|
||||||
|
return telemtClientSecret(baseHex32, "standard", domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool containerStatusRefreshCallPending: false
|
||||||
|
|
||||||
|
function telemtRequestContainerStatusRefresh() {
|
||||||
|
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||||
|
isCheckingStatus = false
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isCheckingStatus = true
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
function telemtScheduleContainerStatusRefresh() {
|
||||||
|
if (containerStatusRefreshCallPending) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
containerStatusRefreshCallPending = true
|
||||||
|
Qt.callLater(function () {
|
||||||
|
containerStatusRefreshCallPending = false
|
||||||
|
root.telemtRequestContainerStatusRefresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function telemtOnPageShown() {
|
||||||
|
if (root.pageOpenHandled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
root.pageOpenHandled = true
|
||||||
|
|
||||||
|
PageController.disableControls(navigationBlockedWhileBusy)
|
||||||
|
|
||||||
|
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||||
|
isCheckingStatus = false
|
||||||
|
} else {
|
||||||
|
isCheckingStatus = true
|
||||||
|
}
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
root.telemtScheduleContainerStatusRefresh()
|
||||||
|
}
|
||||||
|
|
||||||
function telemtScheduleUpdate(closePage) {
|
function telemtScheduleUpdate(closePage) {
|
||||||
var cp = closePage === undefined ? false : closePage
|
var cp = closePage === undefined ? false : closePage
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
@@ -105,12 +189,7 @@ PageType {
|
|||||||
root.savedTlsDomain = TelemtConfigModel.getTlsDomain()
|
root.savedTlsDomain = TelemtConfigModel.getTlsDomain()
|
||||||
root.savedPublicHost = TelemtConfigModel.getPublicHost()
|
root.savedPublicHost = TelemtConfigModel.getPublicHost()
|
||||||
|
|
||||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
Qt.callLater(root.telemtOnPageShown)
|
||||||
isCheckingStatus = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
isCheckingStatus = true
|
|
||||||
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onNavigationBlockedWhileBusyChanged: {
|
onNavigationBlockedWhileBusyChanged: {
|
||||||
@@ -121,10 +200,16 @@ PageType {
|
|||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
|
root.pageOpenHandled = false
|
||||||
|
containerStatusRefreshCallPending = false
|
||||||
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
|
busyIndicatorShown = false
|
||||||
PageController.disableControls(false)
|
PageController.disableControls(false)
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
diagLoading = false
|
diagLoading = false
|
||||||
} else {
|
} else {
|
||||||
PageController.disableControls(navigationBlockedWhileBusy)
|
root.telemtOnPageShown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,8 +221,7 @@ PageType {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (NetworkReachabilityController.hasInternetAccess) {
|
if (NetworkReachabilityController.hasInternetAccess) {
|
||||||
isCheckingStatus = true
|
root.telemtScheduleContainerStatusRefresh()
|
||||||
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,10 +229,15 @@ PageType {
|
|||||||
Connections {
|
Connections {
|
||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
|
function onServerIsBusy(busy) {
|
||||||
|
remoteOperationBusy = busy
|
||||||
|
}
|
||||||
|
|
||||||
function onUpdateContainerFinished(message, closePage) {
|
function onUpdateContainerFinished(message, closePage) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
isCheckingStatus = false
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
@@ -166,9 +255,11 @@ PageType {
|
|||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
isCheckingStatus = false
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isUpdating = false
|
isUpdating = false
|
||||||
|
isFetchingSecret = false
|
||||||
containerStatus = previousContainerStatus
|
containerStatus = previousContainerStatus
|
||||||
TelemtConfigModel.setEnabled(previousEnabled)
|
TelemtConfigModel.setEnabled(previousEnabled)
|
||||||
TelemtConfigModel.setPort(previousPort)
|
TelemtConfigModel.setPort(previousPort)
|
||||||
@@ -181,6 +272,9 @@ PageType {
|
|||||||
TelemtConfigModel.setNatEnabled(previousNatEnabled)
|
TelemtConfigModel.setNatEnabled(previousNatEnabled)
|
||||||
TelemtConfigModel.setNatInternalIp(previousNatInternalIp)
|
TelemtConfigModel.setNatInternalIp(previousNatInternalIp)
|
||||||
TelemtConfigModel.setNatExternalIp(previousNatExternalIp)
|
TelemtConfigModel.setNatExternalIp(previousNatExternalIp)
|
||||||
|
if (previousSecret !== "") {
|
||||||
|
TelemtConfigModel.setSecret(previousSecret)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSetContainerEnabledFinished(enabled) {
|
function onSetContainerEnabledFinished(enabled) {
|
||||||
@@ -190,6 +284,7 @@ PageType {
|
|||||||
}
|
}
|
||||||
if (enabled && pendingUpdateAfterEnable) {
|
if (enabled && pendingUpdateAfterEnable) {
|
||||||
pendingUpdateAfterEnable = false
|
pendingUpdateAfterEnable = false
|
||||||
|
isUpdating = true
|
||||||
root.telemtScheduleUpdate(false)
|
root.telemtScheduleUpdate(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -202,9 +297,9 @@ PageType {
|
|||||||
function onContainerStatusRefreshed(status) {
|
function onContainerStatusRefreshed(status) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
isCheckingStatus = false
|
isCheckingStatus = false
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isCheckingStatus = false
|
|
||||||
containerStatus = status
|
containerStatus = status
|
||||||
|
|
||||||
root.savedTransportMode = TelemtConfigModel.getTransportMode()
|
root.savedTransportMode = TelemtConfigModel.getTransportMode()
|
||||||
@@ -212,11 +307,18 @@ PageType {
|
|||||||
root.savedPublicHost = TelemtConfigModel.getPublicHost()
|
root.savedPublicHost = TelemtConfigModel.getPublicHost()
|
||||||
if (status === 1) {
|
if (status === 1) {
|
||||||
TelemtConfigModel.setEnabled(true)
|
TelemtConfigModel.setEnabled(true)
|
||||||
|
isFetchingSecret = true
|
||||||
|
isCheckingStatus = false
|
||||||
InstallController.fetchContainerSecret(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
InstallController.fetchContainerSecret(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||||
} else if (status === 2) {
|
} else {
|
||||||
|
isFetchingSecret = false
|
||||||
|
isCheckingStatus = false
|
||||||
|
if (status === 2) {
|
||||||
TelemtConfigModel.setEnabled(false)
|
TelemtConfigModel.setEnabled(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
syncPageBusyIndicator()
|
||||||
|
}
|
||||||
|
|
||||||
function onContainerDiagnosticsRefreshed(portReachable, upstreamReachable, clientsConnected, lastConfigRefresh, statsEndpoint) {
|
function onContainerDiagnosticsRefreshed(portReachable, upstreamReachable, clientsConnected, lastConfigRefresh, statsEndpoint) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
@@ -232,20 +334,35 @@ PageType {
|
|||||||
|
|
||||||
function onContainerSecretFetched(secret) {
|
function onContainerSecretFetched(secret) {
|
||||||
if (!root.visible) {
|
if (!root.visible) {
|
||||||
|
isFetchingSecret = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
isFetchingSecret = false
|
||||||
|
syncPageBusyIndicator()
|
||||||
TelemtConfigModel.validateAndSetSecret(secret)
|
TelemtConfigModel.validateAndSetSecret(secret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: contentLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: !root.pageBusy
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20 + SettingsController.safeAreaTopMargin
|
anchors.topMargin: 20 + PageController.safeAreaTopMargin
|
||||||
|
|
||||||
onFocusChanged: {
|
onFocusChanged: {
|
||||||
if (this.activeFocus) connectionListView.positionViewAtBeginning()
|
if (this.activeFocus) {
|
||||||
|
if (mainTabBar.currentIndex === 0) {
|
||||||
|
connectionListView.positionViewAtBeginning()
|
||||||
|
} else {
|
||||||
|
settingsListView.positionViewAtBeginning()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,32 +371,38 @@ PageType {
|
|||||||
anchors.top: backButton.bottom
|
anchors.top: backButton.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 8
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
BaseHeaderType {
|
BaseHeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.topMargin: 8
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
headerText: qsTr("Telemt settings")
|
headerText: qsTr("Telemt settings")
|
||||||
|
descriptionLinkText: qsTr("Read more about this settings")
|
||||||
|
descriptionLinkUrl: "https://github.com/telemt/telemt"
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
CaptionTextType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 0
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
text: qsTr("Read more about this settings")
|
Layout.topMargin: 8
|
||||||
textColor: AmneziaStyle.color.goldenApricot
|
visible: root.telemtNetworkBlocked
|
||||||
clickedFunction: function () {
|
text: qsTr("No internet connection. Connect to the internet to change Telemt settings.")
|
||||||
Qt.openUrlExternally("https://github.com/telemt/telemt")
|
color: AmneziaStyle.color.mutedGray
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
font.pixelSize: 14
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TabBar {
|
TabBar {
|
||||||
id: mainTabBar
|
id: mainTabBar
|
||||||
Layout.fillWidth: true
|
anchors.top: pageHeader.bottom
|
||||||
Layout.topMargin: 4
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: AmneziaStyle.color.transparent
|
color: AmneziaStyle.color.transparent
|
||||||
@@ -300,11 +423,10 @@ PageType {
|
|||||||
isSelected: mainTabBar.currentIndex === 1
|
isSelected: mainTabBar.currentIndex === 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
StackLayout {
|
StackLayout {
|
||||||
id: tabContent
|
id: tabContent
|
||||||
anchors.top: pageHeader.bottom
|
anchors.top: mainTabBar.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -318,36 +440,11 @@ PageType {
|
|||||||
width: connectionListView.width
|
width: connectionListView.width
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
function domainToHex(domain) {
|
|
||||||
var hex = ""
|
|
||||||
for (var i = 0; i < domain.length; i++) {
|
|
||||||
var code = domain.charCodeAt(i).toString(16)
|
|
||||||
hex += (code.length < 2 ? "0" : "") + code
|
|
||||||
}
|
|
||||||
return hex
|
|
||||||
}
|
|
||||||
|
|
||||||
function secretForMode(mode) {
|
|
||||||
if (mode === "faketls") {
|
|
||||||
var domain = root.savedTlsDomain !== "" ? root.savedTlsDomain : TelemtConfigModel.defaultTlsDomain()
|
|
||||||
return "ee" + secret + domainToHex(domain)
|
|
||||||
} else if (mode === "padded") {
|
|
||||||
return "dd" + secret
|
|
||||||
}
|
|
||||||
// Telemt default (secure MTProto, not FakeTLS): Telegram proxy links require dd + hex secret
|
|
||||||
return "dd" + secret
|
|
||||||
}
|
|
||||||
|
|
||||||
property int secretTabIndex: root.syncedSecretTabIndex
|
property int secretTabIndex: root.syncedSecretTabIndex
|
||||||
|
|
||||||
function activeSecret() {
|
function activeSecret() {
|
||||||
if (root.syncedSecretTabIndex === 0) {
|
return root.telemtClientSecretForTabIndex(secret, root.syncedSecretTabIndex,
|
||||||
return secretForMode("standard")
|
root.savedTlsDomain, TelemtConfigModel.defaultTlsDomain())
|
||||||
}
|
|
||||||
if (root.syncedSecretTabIndex === 1) {
|
|
||||||
return secretForMode("padded")
|
|
||||||
}
|
|
||||||
return secretForMode("faketls")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function effectiveSecret() {
|
function effectiveSecret() {
|
||||||
@@ -690,6 +787,11 @@ PageType {
|
|||||||
width: settingsListView.width
|
width: settingsListView.width
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
function telemtActiveSecretForBaseHex(baseHex) {
|
||||||
|
return root.telemtClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex,
|
||||||
|
root.savedTlsDomain, TelemtConfigModel.defaultTlsDomain())
|
||||||
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
id: enableTelemtSwitch
|
id: enableTelemtSwitch
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -699,11 +801,13 @@ PageType {
|
|||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
text: qsTr("Enable Telemt")
|
text: qsTr("Enable Telemt")
|
||||||
checked: isEnabled
|
checked: isEnabled
|
||||||
enabled: !isCheckingStatus && containerStatus !== 0 && containerStatus !== 3 && !isUpdating
|
enabled: containerStatus !== 0 && containerStatus !== 3 && !root.pageBusy
|
||||||
|
&& !root.telemtNetworkBlocked
|
||||||
onToggled: function () {
|
onToggled: function () {
|
||||||
if (checked !== isEnabled) {
|
if (checked !== isEnabled) {
|
||||||
previousEnabled = isEnabled
|
previousEnabled = isEnabled
|
||||||
previousContainerStatus = containerStatus
|
previousContainerStatus = containerStatus
|
||||||
|
root.previousSecret = secret
|
||||||
isEnabled = checked
|
isEnabled = checked
|
||||||
isUpdating = true
|
isUpdating = true
|
||||||
if (checked) {
|
if (checked) {
|
||||||
@@ -736,13 +840,14 @@ PageType {
|
|||||||
|
|
||||||
CaptionTextType {
|
CaptionTextType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: secret !== "" ? secret : qsTr("Not generated")
|
text: secret !== "" ? telemtActiveSecretForBaseHex(secret) : qsTr("Not generated")
|
||||||
color: secret !== "" ? AmneziaStyle.color.paleGray : AmneziaStyle.color.mutedGray
|
color: secret !== "" ? AmneziaStyle.color.paleGray : AmneziaStyle.color.mutedGray
|
||||||
elide: Text.ElideMiddle
|
wrapMode: Text.WrapAnywhere
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
implicitWidth: 36
|
implicitWidth: 36
|
||||||
implicitHeight: 36
|
implicitHeight: 36
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
@@ -750,12 +855,14 @@ PageType {
|
|||||||
imageColor: AmneziaStyle.color.paleGray
|
imageColor: AmneziaStyle.color.paleGray
|
||||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
var secretSnapshot = secret
|
||||||
showQuestionDrawer(
|
showQuestionDrawer(
|
||||||
qsTr("Generate new secret?"),
|
qsTr("Generate new secret?"),
|
||||||
qsTr("All existing connection links will stop working. Users will need new links."),
|
qsTr("All existing connection links will stop working. Users will need new links."),
|
||||||
qsTr("Generate"),
|
qsTr("Generate"),
|
||||||
qsTr("Cancel"),
|
qsTr("Cancel"),
|
||||||
function () {
|
function () {
|
||||||
|
root.previousSecret = secretSnapshot
|
||||||
if (containerStatus === 1) {
|
if (containerStatus === 1) {
|
||||||
isUpdating = true
|
isUpdating = true
|
||||||
TelemtConfigModel.generateSecret()
|
TelemtConfigModel.generateSecret()
|
||||||
@@ -926,6 +1033,7 @@ PageType {
|
|||||||
clickedFunction: function () {
|
clickedFunction: function () {
|
||||||
transportMode = (index === 0) ? "standard" : "faketls"
|
transportMode = (index === 0) ? "standard" : "faketls"
|
||||||
TelemtConfigModel.setTransportMode(transportMode)
|
TelemtConfigModel.setTransportMode(transportMode)
|
||||||
|
root.syncedSecretTabIndex = transportMode === "faketls" ? 1 : 0
|
||||||
transportModeDropDown.closeTriggered()
|
transportModeDropDown.closeTriggered()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1406,6 +1514,7 @@ PageType {
|
|||||||
previousNatEnabled = natEnabled
|
previousNatEnabled = natEnabled
|
||||||
previousNatInternalIp = natInternalIp
|
previousNatInternalIp = natInternalIp
|
||||||
previousNatExternalIp = natExternalIp
|
previousNatExternalIp = natExternalIp
|
||||||
|
root.previousSecret = secret
|
||||||
isUpdating = true
|
isUpdating = true
|
||||||
root.telemtScheduleUpdate(false)
|
root.telemtScheduleUpdate(false)
|
||||||
}
|
}
|
||||||
@@ -1414,34 +1523,5 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
visible: isCheckingStatus || isUpdating || root.telemtNetworkBlocked
|
|
||||||
color: AmneziaStyle.color.midnightBlack
|
|
||||||
opacity: 0.6
|
|
||||||
z: 1
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
BusyIndicator {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: isCheckingStatus || isUpdating
|
|
||||||
running: isCheckingStatus || isUpdating
|
|
||||||
width: 48
|
|
||||||
height: 48
|
|
||||||
}
|
|
||||||
CaptionTextType {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.leftMargin: 24
|
|
||||||
anchors.rightMargin: 24
|
|
||||||
visible: root.telemtNetworkBlocked && !isCheckingStatus && !isUpdating
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("No internet connection. Connect to the internet to change Telemt settings.")
|
|
||||||
color: AmneziaStyle.color.paleGray
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
font.pixelSize: 14
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user