add CAPTCHA refreshed

This commit is contained in:
Pavel Yaumenau
2026-04-28 15:16:45 +03:00
parent 118d11c194
commit e5bbfe0036
9 changed files with 89 additions and 2 deletions

View File

@@ -201,6 +201,9 @@ amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &ssl
}
if (status == httpStatusCodePaymentRequired) {
const QString errorToken = apiErrorTokenFromJson(jsonObj);
if (errorToken.contains(QLatin1String("refresh_captcha"), Qt::CaseInsensitive)) {
return amnezia::ErrorCode::ApiCaptchaRefreshError;
}
if (errorToken.contains(QLatin1String("invalid_captcha"), Qt::CaseInsensitive)) {
return amnezia::ErrorCode::ApiCaptchaInvalidError;
}

View File

@@ -482,7 +482,7 @@ bool GatewayController::shouldBypassProxy(const QNetworkReply::NetworkError &rep
return false;
}
const QString err = jsonObj.value(QStringLiteral("error")).toString();
if (err.contains(QLatin1String("captcha"), Qt::CaseInsensitive) || err == QLatin1String("rate_limit_exceeded")) {
if (err.contains(QLatin1String("captcha"), Qt::CaseInsensitive) || err == QLatin1String("rate_limit_exceeded") || err == QLatin1String("refresh_captcha")) {
return false;
}
}

View File

@@ -128,7 +128,8 @@ namespace amnezia
ApiTrialAlreadyUsedError = 1116,
ApiCaptchaRequiredError = 1117,
ApiCaptchaInvalidError = 1118,
ApiRateLimitError = 1119,
ApiCaptchaRefreshError = 1119,
ApiRateLimitError = 1120,
// QFile errors
OpenError = 1200,

View File

@@ -85,6 +85,7 @@ QString errorString(ErrorCode code) {
case (ErrorCode::ApiTrialAlreadyUsedError): errorMessage = QObject::tr("This email address has already been used to activate a trial"); break;
case (ErrorCode::ApiCaptchaRequiredError): errorMessage = QObject::tr("CAPTCHA verification is required"); break;
case (ErrorCode::ApiCaptchaInvalidError): errorMessage = QObject::tr("CAPTCHA was incorrect. Please try again"); break;
case (ErrorCode::ApiCaptchaRefreshError): errorMessage = QObject::tr("CAPTCHA refreshed. Please try again"); break;
case (ErrorCode::ApiRateLimitError): errorMessage = QObject::tr("Too many requests. Please try again later"); break;
// QFile errors

View File

@@ -1371,3 +1371,39 @@ void ApiConfigsController::onCaptchaSolved(const QString &captchaId, const QStri
m_serversModel->addServer(serverConfig);
emit installServerFromApiFinished(tr("%1 installed successfully.").arg(m_apiServicesModel->getSelectedServiceName()));
}
void ApiConfigsController::onRefreshCaptchaRequested() {
if (!m_captchaState.isPending) {
emit errorOccurred(ErrorCode::InternalError);
return;
}
QJsonObject apiPayload = m_captchaState.apiPayload;
apiPayload.insert("refresh_captcha", true);
QByteArray responseBody;
ErrorCode errorCode = executeRequest(m_captchaState.endpoint, apiPayload, responseBody);
if (errorCode != ErrorCode::NoError) {
emit errorOccurred(errorCode);
return;
}
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseBody);
if (!jsonDoc.isObject()) {
emit errorOccurred(ErrorCode::InternalError);
return;
}
QJsonObject jsonObj = jsonDoc.object();
QString newCaptchaId = jsonObj.value("captcha_id").toString();
QString newCaptchaImage = jsonObj.value("captcha_image").toString();
QString hint = jsonObj.value("hint").toString(tr("CAPTCHA refreshed"));
// Обновляем state (важно!)
m_captchaState.apiPayload = apiPayload;
m_captchaState.isPending = true;
emit captchaRequired(newCaptchaId, newCaptchaImage, hint);
}

View File

@@ -50,6 +50,7 @@ public slots:
bool isVlessProtocol();
void onCaptchaSolved(const QString &captchaId, const QString &solution);
void onRefreshCaptchaRequested();
signals:
void errorOccurred(ErrorCode errorCode);

View File

@@ -15,6 +15,7 @@ Popup {
property string hint: "Please solve the CAPTCHA to continue"
signal captchaSolved(string captchaId, string solution)
signal refreshCaptchaRequested()
leftMargin: 25
rightMargin: 25
@@ -118,6 +119,26 @@ Popup {
}
}
RowLayout {
Layout.fillWidth: true
spacing: 8
ParagraphTextType {
text: qsTr("Can't read the image?")
Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
}
BasicButtonType {
text: qsTr("Refresh")
implicitHeight: 32
onClicked: {
root.refreshCaptchaRequested()
}
}
}
ParagraphTextType {
text: qsTr("Enter the numbers from the image:")
Layout.fillWidth: true

View File

@@ -213,6 +213,10 @@ Window {
captchaDialog.close()
ApiConfigsController.onCaptchaSolved(captchaId, solution)
}
onRefreshCaptchaRequested: function() {
ApiConfigsController.onRefreshCaptchaRequested()
}
}
}