fix cloudflare verification

This commit is contained in:
2025-01-31 10:46:24 +08:00
parent d99a30b7d8
commit d675af3fb4
3 changed files with 45 additions and 38 deletions

View File

@@ -318,7 +318,9 @@
"Deselect All": "取消全选", "Deselect All": "取消全选",
"Add keyword": "添加关键词", "Add keyword": "添加关键词",
"Keyword": "关键词", "Keyword": "关键词",
"Manage": "管理" "Manage": "管理",
"Verify": "验证",
"Cloudflare verification required": "需要Cloudflare验证"
}, },
"zh_TW": { "zh_TW": {
"Home": "首頁", "Home": "首頁",
@@ -639,6 +641,8 @@
"Deselect All": "取消全選", "Deselect All": "取消全選",
"Add keyword": "添加關鍵詞", "Add keyword": "添加關鍵詞",
"Keyword": "關鍵詞", "Keyword": "關鍵詞",
"Manage": "管理" "Manage": "管理",
"Verify": "驗證",
"Cloudflare verification required": "需要Cloudflare驗證"
} }
} }

View File

@@ -57,7 +57,9 @@ class NetworkError extends StatelessWidget {
if (cfe != null) if (cfe != null)
FilledButton( FilledButton(
onPressed: () => passCloudflare( onPressed: () => passCloudflare(
CloudflareException.fromString(message)!, retry!), CloudflareException.fromString(message)!,
retry!,
),
child: Text('Verify'.tl), child: Text('Verify'.tl),
) )
else else
@@ -130,7 +132,7 @@ abstract class LoadingState<T extends StatefulWidget, S extends Object>
if (res.success) { if (res.success) {
return res; return res;
} else { } else {
if(!mounted) return res; if (!mounted) return res;
if (retry >= 3) { if (retry >= 3) {
return res; return res;
} }
@@ -188,7 +190,7 @@ abstract class LoadingState<T extends StatefulWidget, S extends Object>
isLoading = true; isLoading = true;
Future.microtask(() { Future.microtask(() {
loadDataWithRetry().then((value) async { loadDataWithRetry().then((value) async {
if(!mounted) return; if (!mounted) return;
if (value.success) { if (value.success) {
data = value.data; data = value.data;
await onDataLoaded(); await onDataLoaded();
@@ -321,21 +323,11 @@ abstract class MultiPageLoadingState<T extends StatefulWidget, S extends Object>
} }
Widget buildError(BuildContext context, String error) { Widget buildError(BuildContext context, String error) {
return Center( return NetworkError(
child: Column( withAppbar: false,
mainAxisSize: MainAxisSize.min, message: error,
children: [ retry: reset,
Text(error, maxLines: 3), );
const SizedBox(height: 12),
Button.outlined(
onPressed: () {
reset();
},
child: const Text("Retry"),
)
],
),
).paddingHorizontal(16);
} }
@override @override

View File

@@ -1,6 +1,7 @@
import 'dart:io' as io; import 'dart:io' as io;
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:venera/foundation/app.dart'; import 'package:venera/foundation/app.dart';
import 'package:venera/foundation/appdata.dart'; import 'package:venera/foundation/appdata.dart';
import 'package:venera/foundation/consts.dart'; import 'package:venera/foundation/consts.dart';
@@ -58,7 +59,7 @@ class CloudflareException implements DioException {
class CloudflareInterceptor extends Interceptor { class CloudflareInterceptor extends Interceptor {
@override @override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) { void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if(options.headers['cookie'].toString().contains('cf_clearance')) { if (options.headers['cookie'].toString().contains('cf_clearance')) {
options.headers['user-agent'] = appdata.implicitData['ua'] ?? webUA; options.headers['user-agent'] = appdata.implicitData['ua'] ?? webUA;
} }
handler.next(options); handler.next(options);
@@ -129,7 +130,7 @@ void passCloudflare(CloudflareException e, void Function() onFinished) async {
appdata.writeImplicitData(); appdata.writeImplicitData();
} }
var cookiesMap = await controller.getCookies(url); var cookiesMap = await controller.getCookies(url);
if(cookiesMap['cf_clearance'] == null) { if (cookiesMap['cf_clearance'] == null) {
return; return;
} }
saveCookies(cookiesMap); saveCookies(cookiesMap);
@@ -137,30 +138,40 @@ void passCloudflare(CloudflareException e, void Function() onFinished) async {
onFinished(); onFinished();
} }
}, },
onClose: onFinished,
); );
webview.open(); webview.open();
} else { } else {
void check(InAppWebViewController controller) async {
var res = await controller.platform.evaluateJavascript(
source:
"document.head.innerHTML.includes('#challenge-success-text')");
if (res == false) {
var ua = await controller.getUA();
if (ua != null) {
appdata.implicitData['ua'] = ua;
appdata.writeImplicitData();
}
var cookies = await controller.getCookies(url) ?? [];
if (cookies.firstWhereOrNull(
(element) => element.name == 'cf_clearance') ==
null) {
return;
}
SingleInstanceCookieJar.instance?.saveFromResponse(uri, cookies);
App.rootPop();
}
}
await App.rootContext.to( await App.rootContext.to(
() => AppWebview( () => AppWebview(
initialUrl: url, initialUrl: url,
singlePage: true, singlePage: true,
onTitleChange: (title, controller) async {
check(controller);
},
onLoadStop: (controller) async { onLoadStop: (controller) async {
var res = await controller.platform.evaluateJavascript( check(controller);
source:
"document.head.innerHTML.includes('#challenge-success-text')");
if (res == false) {
var ua = await controller.getUA();
if (ua != null) {
appdata.implicitData['ua'] = ua;
appdata.writeImplicitData();
}
var cookies = await controller.getCookies(url) ?? [];
if(cookies.firstWhereOrNull((element) => element.name == 'cf_clearance') == null) {
return;
}
SingleInstanceCookieJar.instance?.saveFromResponse(uri, cookies);
App.rootPop();
}
}, },
onStarted: (controller) async { onStarted: (controller) async {
var ua = await controller.getUA(); var ua = await controller.getUA();