diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7f408550..b4802b26 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,7 +11,7 @@
- Added `contentWorld` argument to `evaluateJavascript` WebView method
- Added `isDirectionalLockEnabled`, `mediaType`, `pageZoom`, `limitsNavigationsToAppBoundDomains`, `useOnNavigationResponse` iOS-specific WebView options
- Added `handlesURLScheme`, `createPdf`, `createWebArchiveData` iOS-specific WebView methods
-- Added `iosOnNavigationResponse` iOS-specific WebView events
+- Added `iosOnNavigationResponse` and `iosShouldAllowDeprecatedTLS` iOS-specific WebView events
- Added `iosAnimated` optional argument to `zoomBy` WebView method
- Added `screenshotConfiguration` optional argument to `takeScreenshot` WebView method
- Added `scriptHtmlTagAttributes` optional argument to `injectJavascriptFileFromUrl` WebView method
@@ -50,6 +50,7 @@
- Added `callAsyncJavaScript` name to the list of javaScriptHandlerForbiddenNames
- Changed `zoomBy` WebView method signature
- Moved `saveWebArchive` WebView method from Android-specific to cross-platform
+- Renamed `HttpAuthChallenge` to `URLAuthenticationChallenge`
## 4.0.0+4
diff --git a/README.md b/README.md
index 97f46a5c..e1ffa9be 100755
--- a/README.md
+++ b/README.md
@@ -719,6 +719,8 @@ Event names that starts with `android` or `ios` are events platform-specific.
* `androidOnReceivedLoginRequest`: Event fired when a request to automatically log in the user has been processed (available only on Android).
* `iosOnWebContentProcessDidTerminate`: Invoked when the web view's web content process is terminated (available only on iOS).
* `iosOnDidReceiveServerRedirectForProvisionalNavigation`: Called when a web view receives a server redirect (available only on iOS).
+* `iosOnNavigationResponse`: Called when a web view asks for permission to navigate to new content after the response to the navigation request is known (available only on iOS).
+* `iosShouldAllowDeprecatedTLS`: Called when a web view asks whether to continue with a connection that uses a deprecated version of TLS (v1.0 and v1.1) (available only on iOS).
### `ContextMenu` class
diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist
index df18581f..d62ce85a 100755
--- a/example/ios/Runner/Info.plist
+++ b/example/ios/Runner/Info.plist
@@ -28,6 +28,8 @@
NSAppTransportSecurity
+ NSAllowsArbitraryLoads
+
NSAllowsLocalNetworking
diff --git a/ios/Classes/InAppWebView.swift b/ios/Classes/InAppWebView.swift
index 072077ff..ae9e5cb8 100755
--- a/ios/Classes/InAppWebView.swift
+++ b/ios/Classes/InAppWebView.swift
@@ -3106,6 +3106,39 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
return windowWebView
}
+ public func webView(_ webView: WKWebView,
+ authenticationChallenge challenge: URLAuthenticationChallenge,
+ shouldAllowDeprecatedTLS decisionHandler: @escaping (Bool) -> Void) {
+ shouldAllowDeprecatedTLS(challenge: challenge, result: {(result) -> Void in
+ if result is FlutterError {
+ print((result as! FlutterError).message ?? "")
+ }
+ else if (result as? NSObject) == FlutterMethodNotImplemented {
+ decisionHandler(false)
+ }
+ else {
+ var response: [String: Any]
+ if let r = result {
+ response = r as! [String: Any]
+ var action = response["action"] as? Int
+ action = action != nil ? action : 0;
+ switch action {
+ case 0:
+ decisionHandler(false)
+ break
+ case 1:
+ decisionHandler(true)
+ break
+ default:
+ decisionHandler(false)
+ }
+ return;
+ }
+ decisionHandler(false)
+ }
+ })
+ }
+
public func webViewDidClose(_ webView: WKWebView) {
let arguments: [String: Any?] = [:]
channel?.invokeMethod("onCloseWindow", arguments: arguments)
@@ -3396,6 +3429,17 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
channel?.invokeMethod("onReceivedClientCertRequest", arguments: arguments, result: result)
}
+ public func shouldAllowDeprecatedTLS(challenge: URLAuthenticationChallenge, result: FlutterResult?) {
+ let arguments: [String: Any?] = [
+ "host": challenge.protectionSpace.host,
+ "protocol": challenge.protectionSpace.protocol,
+ "realm": challenge.protectionSpace.realm,
+ "port": challenge.protectionSpace.port,
+ "previousFailureCount": challenge.previousFailureCount
+ ]
+ channel?.invokeMethod("shouldAllowDeprecatedTLS", arguments: arguments, result: result)
+ }
+
public func onJsAlert(frame: WKFrameInfo, message: String, result: FlutterResult?) {
let arguments: [String: Any?] = [
"url": frame.request.url?.absoluteString,
diff --git a/lib/src/headless_in_app_webview.dart b/lib/src/headless_in_app_webview.dart
index aebc558e..8652d969 100644
--- a/lib/src/headless_in_app_webview.dart
+++ b/lib/src/headless_in_app_webview.dart
@@ -78,6 +78,7 @@ class HeadlessInAppWebView implements WebView {
this.iosOnWebContentProcessDidTerminate,
this.iosOnDidReceiveServerRedirectForProvisionalNavigation,
this.iosOnNavigationResponse,
+ this.iosShouldAllowDeprecatedTLS,
this.initialUrl,
this.initialFile,
this.initialData,
@@ -196,6 +197,11 @@ class HeadlessInAppWebView implements WebView {
IOSNavigationResponse navigationResponse)?
iosOnNavigationResponse;
+ @override
+ final Future Function(InAppWebViewController controller,
+ URLAuthenticationChallenge challenge)?
+ iosShouldAllowDeprecatedTLS;
+
@override
final Future Function(
InAppWebViewController controller, AjaxRequest ajaxRequest)?
@@ -293,7 +299,7 @@ class HeadlessInAppWebView implements WebView {
@override
final Future Function(
- InAppWebViewController controller, HttpAuthChallenge challenge)?
+ InAppWebViewController controller, URLAuthenticationChallenge challenge)?
onReceivedHttpAuthRequest;
@override
diff --git a/lib/src/in_app_browser.dart b/lib/src/in_app_browser.dart
index 79b32f28..35db52d0 100755
--- a/lib/src/in_app_browser.dart
+++ b/lib/src/in_app_browser.dart
@@ -418,13 +418,13 @@ class InAppBrowser {
///Event fired when the WebView received an HTTP authentication request. The default behavior is to cancel the request.
///
- ///[challenge] contains data about host, port, protocol, realm, etc. as specified in the [HttpAuthChallenge].
+ ///[challenge] contains data about host, port, protocol, realm, etc. as specified in the [URLAuthenticationChallenge].
///
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String)
///
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
Future? onReceivedHttpAuthRequest(
- HttpAuthChallenge challenge) {}
+ URLAuthenticationChallenge challenge) {}
///Event fired when the WebView need to perform server trust authentication (certificate validation).
///The host application must return either [ServerTrustAuthResponse] instance with [ServerTrustAuthResponseAction.CANCEL] or [ServerTrustAuthResponseAction.PROCEED].
@@ -763,6 +763,16 @@ class InAppBrowser {
Future?
iosOnNavigationResponse(IOSNavigationResponse navigationResponse) {}
+ ///Called when a web view asks whether to continue with a connection that uses a deprecated version of TLS (v1.0 and v1.1).
+ ///
+ ///[challenge] represents the authentication challenge.
+ ///
+ ///**NOTE**: available only on iOS 14.0+.
+ ///
+ ///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/3601237-webview
+ Future?
+ iosShouldAllowDeprecatedTLS(URLAuthenticationChallenge challenge) {}
+
void throwIsAlreadyOpened({String message = ''}) {
if (this.isOpened()) {
throw Exception([
diff --git a/lib/src/in_app_webview.dart b/lib/src/in_app_webview.dart
index 77a66bb8..abe84b18 100755
--- a/lib/src/in_app_webview.dart
+++ b/lib/src/in_app_webview.dart
@@ -90,6 +90,7 @@ class InAppWebView extends StatefulWidget implements WebView {
this.iosOnWebContentProcessDidTerminate,
this.iosOnDidReceiveServerRedirectForProvisionalNavigation,
this.iosOnNavigationResponse,
+ this.iosShouldAllowDeprecatedTLS,
this.gestureRecognizers,
}) : super(key: key);
@@ -157,6 +158,11 @@ class InAppWebView extends StatefulWidget implements WebView {
IOSNavigationResponse navigationResponse)?
iosOnNavigationResponse;
+ @override
+ final Future Function(InAppWebViewController controller,
+ URLAuthenticationChallenge challenge)?
+ iosShouldAllowDeprecatedTLS;
+
@override
final Future Function(
InAppWebViewController controller, AjaxRequest ajaxRequest)?
@@ -263,7 +269,7 @@ class InAppWebView extends StatefulWidget implements WebView {
@override
final Future Function(
- InAppWebViewController controller, HttpAuthChallenge challenge)?
+ InAppWebViewController controller, URLAuthenticationChallenge challenge)?
onReceivedHttpAuthRequest;
@override
diff --git a/lib/src/in_app_webview_controller.dart b/lib/src/in_app_webview_controller.dart
index b4441e7a..b615e79b 100644
--- a/lib/src/in_app_webview_controller.dart
+++ b/lib/src/in_app_webview_controller.dart
@@ -489,7 +489,7 @@ class InAppWebViewController {
int previousFailureCount = call.arguments["previousFailureCount"];
var protectionSpace = ProtectionSpace(
host: host, protocol: protocol, realm: realm, port: port);
- var challenge = HttpAuthChallenge(
+ var challenge = URLAuthenticationChallenge(
previousFailureCount: previousFailureCount,
protectionSpace: protectionSpace);
if (_webview != null && _webview!.onReceivedHttpAuthRequest != null)
@@ -675,6 +675,27 @@ class InAppWebViewController {
.iosOnNavigationResponse(iosOnNavigationResponse))
?.toMap();
break;
+ case "shouldAllowDeprecatedTLS":
+ String host = call.arguments["host"];
+ String protocol = call.arguments["protocol"];
+ String? realm = call.arguments["realm"];
+ int? port = call.arguments["port"];
+ int previousFailureCount = call.arguments["previousFailureCount"];
+ var protectionSpace = ProtectionSpace(
+ host: host, protocol: protocol, realm: realm, port: port);
+ var challenge = URLAuthenticationChallenge(
+ previousFailureCount: previousFailureCount,
+ protectionSpace: protectionSpace);
+
+ if (_webview != null && _webview!.iosShouldAllowDeprecatedTLS != null)
+ return (await _webview!.iosShouldAllowDeprecatedTLS!(
+ this, challenge))
+ ?.toMap();
+ else if (_inAppBrowser != null)
+ return (await _inAppBrowser!
+ .iosShouldAllowDeprecatedTLS(challenge))
+ ?.toMap();
+ break;
case "onLongPressHitTestResult":
Map? hitTestResultMap =
call.arguments["hitTestResult"];
diff --git a/lib/src/types.dart b/lib/src/types.dart
index 0132c3bf..74f72420 100755
--- a/lib/src/types.dart
+++ b/lib/src/types.dart
@@ -995,14 +995,14 @@ class HttpAuthResponse {
///Class that represents the challenge of the [WebView.onReceivedHttpAuthRequest] event.
///It provides all the information about the challenge.
-class HttpAuthChallenge {
+class URLAuthenticationChallenge {
///A count of previous failed authentication attempts.
int previousFailureCount;
///The protection space requiring authentication.
ProtectionSpace? protectionSpace;
- HttpAuthChallenge(
+ URLAuthenticationChallenge(
{required this.previousFailureCount, required this.protectionSpace});
Map toMap() {
@@ -5532,3 +5532,30 @@ class IOSNavigationResponseAction {
};
}
}
+
+///Class that is used by [WebView.iosShouldAllowDeprecatedTLS] event.
+///It represents the policy to pass back to the decision handler.
+class IOSShouldAllowDeprecatedTLSAction {
+ final int _value;
+
+ const IOSShouldAllowDeprecatedTLSAction._internal(this._value);
+
+ int toValue() => _value;
+
+ ///Cancel the navigation.
+ static const CANCEL = const IOSShouldAllowDeprecatedTLSAction._internal(0);
+
+ ///Allow the navigation to continue.
+ static const ALLOW = const IOSShouldAllowDeprecatedTLSAction._internal(1);
+
+ bool operator ==(value) => value == _value;
+
+ @override
+ int get hashCode => _value.hashCode;
+
+ Map toMap() {
+ return {
+ "action": _value,
+ };
+ }
+}
diff --git a/lib/src/webview.dart b/lib/src/webview.dart
index 251250a1..a2220735 100644
--- a/lib/src/webview.dart
+++ b/lib/src/webview.dart
@@ -218,13 +218,13 @@ abstract class WebView {
///Event fired when the WebView received an HTTP authentication request. The default behavior is to cancel the request.
///
- ///[challenge] contains data about host, port, protocol, realm, etc. as specified in the [HttpAuthChallenge].
+ ///[challenge] contains data about host, port, protocol, realm, etc. as specified in the [URLAuthenticationChallenge].
///
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String)
///
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
final Future Function(
- InAppWebViewController controller, HttpAuthChallenge challenge)?
+ InAppWebViewController controller, URLAuthenticationChallenge challenge)?
onReceivedHttpAuthRequest;
///Event fired when the WebView need to perform server trust authentication (certificate validation).
@@ -615,6 +615,17 @@ abstract class WebView {
IOSNavigationResponse navigationResponse)?
iosOnNavigationResponse;
+ ///Called when a web view asks whether to continue with a connection that uses a deprecated version of TLS (v1.0 and v1.1).
+ ///
+ ///[challenge] represents the authentication challenge.
+ ///
+ ///**NOTE**: available only on iOS 14.0+.
+ ///
+ ///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/3601237-webview
+ final Future Function(InAppWebViewController controller,
+ URLAuthenticationChallenge challenge)?
+ iosShouldAllowDeprecatedTLS;
+
///Initial url that will be loaded.
final String? initialUrl;
@@ -692,6 +703,7 @@ abstract class WebView {
this.iosOnWebContentProcessDidTerminate,
this.iosOnDidReceiveServerRedirectForProvisionalNavigation,
this.iosOnNavigationResponse,
+ this.iosShouldAllowDeprecatedTLS,
this.initialUrl,
this.initialFile,
this.initialData,