CookieManager.deleteCookie and CookieManager.deleteCookies now have the domain argument optional and without a default value

This commit is contained in:
Lorenzo Pichilli 2022-10-14 00:47:54 +02:00
parent 0da11b34ff
commit 083d1ffffd
6 changed files with 81 additions and 36 deletions

View File

@ -18,6 +18,10 @@
- Merged "Add directoryIndex and documentRoot to InAppLocalhostServer option" [#1319](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1319) (thanks to [fa0311](https://github.com/fa0311)) - Merged "Add directoryIndex and documentRoot to InAppLocalhostServer option" [#1319](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1319) (thanks to [fa0311](https://github.com/fa0311))
- Merged "fix(ios): invoke onBrowserCreated when viewDidLoad is called with win…" [#1344](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1344) (thanks to [perffecto](https://github.com/perffecto)) - Merged "fix(ios): invoke onBrowserCreated when viewDidLoad is called with win…" [#1344](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1344) (thanks to [perffecto](https://github.com/perffecto))
### BREAKING CHANGES
- `CookieManager.getCookie`, `CookieManager.deleteCookie` and `CookieManager.deleteCookies` have the `domain` argument optional and without a default value
## 5.4.4+3 ## 5.4.4+3
- Removed Android unsafe trust manager - Removed Android unsafe trust manager

View File

@ -171,13 +171,16 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
}); });
cookieManager.flush(); cookieManager.flush();
} }
else { else if (plugin != null) {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext); CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync(); cookieSyncMngr.startSync();
cookieManager.setCookie(url, cookieValue); cookieManager.setCookie(url, cookieValue);
result.success(true); result.success(true);
cookieSyncMngr.stopSync(); cookieSyncMngr.stopSync();
cookieSyncMngr.sync(); cookieSyncMngr.sync();
} else {
cookieManager.setCookie(url, cookieValue);
result.success(true);
} }
} }
@ -218,7 +221,12 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
cookieManager = getCookieManager(); cookieManager = getCookieManager();
if (cookieManager == null) return; if (cookieManager == null) return;
String cookieValue = name + "=; Path=" + path + "; Domain=" + domain + "; Max-Age=-1;"; String cookieValue = name + "=; Path=" + path + "; Max-Age=-1";
if (domain != null)
cookieValue += "; Domain=" + domain;
cookieValue += ";";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.setCookie(url, cookieValue, new ValueCallback<Boolean>() { cookieManager.setCookie(url, cookieValue, new ValueCallback<Boolean>() {
@ -229,13 +237,16 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
}); });
cookieManager.flush(); cookieManager.flush();
} }
else { else if (plugin != null) {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext); CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync(); cookieSyncMngr.startSync();
cookieManager.setCookie(url, cookieValue); cookieManager.setCookie(url, cookieValue);
result.success(true); result.success(true);
cookieSyncMngr.stopSync(); cookieSyncMngr.stopSync();
cookieSyncMngr.sync(); cookieSyncMngr.sync();
} else {
cookieManager.setCookie(url, cookieValue);
result.success(true);
} }
} }
@ -248,7 +259,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
String cookiesString = cookieManager.getCookie(url); String cookiesString = cookieManager.getCookie(url);
if (cookiesString != null) { if (cookiesString != null) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && plugin != null) {
cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext); cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync(); cookieSyncMngr.startSync();
} }
@ -257,7 +268,14 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
for (String cookie : cookies) { for (String cookie : cookies) {
String[] nameValue = cookie.split("=", 2); String[] nameValue = cookie.split("=", 2);
String name = nameValue[0].trim(); String name = nameValue[0].trim();
String cookieValue = name + "=; Path=" + path + "; Domain=" + domain + "; Max-Age=-1;";
String cookieValue = name + "=; Path=" + path + "; Max-Age=-1";
if (domain != null)
cookieValue += "; Domain=" + domain;
cookieValue += ";";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
cookieManager.setCookie(url, cookieValue, null); cookieManager.setCookie(url, cookieValue, null);
else else
@ -286,13 +304,16 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
}); });
cookieManager.flush(); cookieManager.flush();
} }
else { else if (plugin != null) {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext); CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync(); cookieSyncMngr.startSync();
cookieManager.removeAllCookie(); cookieManager.removeAllCookie();
result.success(true); result.success(true);
cookieSyncMngr.stopSync(); cookieSyncMngr.stopSync();
cookieSyncMngr.sync(); cookieSyncMngr.sync();
} else {
cookieManager.removeAllCookie();
result.success(true);
} }
} }

View File

@ -5578,7 +5578,7 @@ setTimeout(function() {
cookie = await cookieManager.getCookie(url: url, name: "myCookie"); cookie = await cookieManager.getCookie(url: url, name: "myCookie");
expect(cookie, isNull); expect(cookie, isNull);
await cookieManager.deleteCookies(url: url); await cookieManager.deleteCookies(url: url, domain: ".flutter.dev");
cookies = await cookieManager.getCookies(url: url); cookies = await cookieManager.getCookies(url: url);
expect(cookies, isEmpty); expect(cookies, isEmpty);
}); });

View File

@ -118,7 +118,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
key: webViewKey, key: webViewKey,
// contextMenu: contextMenu, // contextMenu: contextMenu,
initialUrlRequest: initialUrlRequest:
URLRequest(url: Uri.parse("https://github.com/flutter")), URLRequest(url: Uri.parse("https://flutter.dev/")),
// initialFile: "assets/index.html", // initialFile: "assets/index.html",
initialUserScripts: UnmodifiableListView<UserScript>([]), initialUserScripts: UnmodifiableListView<UserScript>([]),
initialOptions: options, initialOptions: options,
@ -169,6 +169,26 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
this.url = url.toString(); this.url = url.toString();
urlController.text = this.url; urlController.text = this.url;
}); });
CookieManager cookieManager = CookieManager.instance();
await cookieManager.setCookie(
url: url!, name: "myCookie", value: "myValue");
List<Cookie> cookies = await cookieManager.getCookies(url: url);
print(cookies);
Cookie? cookie =
await cookieManager.getCookie(url: url, name: "myCookie");
print(cookie);
await cookieManager.deleteCookie(url: url, name: "myCookie", domain: ".flutter.dev");
cookie = await cookieManager.getCookie(url: url, name: "myCookie");
print(cookie);
await cookieManager.deleteCookies(url: url, domain: ".flutter.dev");
await Future.delayed(Duration(seconds: 1));
cookies = await cookieManager.getCookies(url: url);
print(cookies);
}, },
onLoadError: (controller, url, code, message) { onLoadError: (controller, url, code, message) {
pullToRefreshController.endRefreshing(); pullToRefreshController.endRefreshing();

View File

@ -70,15 +70,15 @@ class MyCookieManager: NSObject, FlutterPlugin {
case "deleteCookie": case "deleteCookie":
let url = arguments!["url"] as! String let url = arguments!["url"] as! String
let name = arguments!["name"] as! String let name = arguments!["name"] as! String
let domain = arguments!["domain"] as! String
let path = arguments!["path"] as! String let path = arguments!["path"] as! String
MyCookieManager.deleteCookie(url: url, name: name, domain: domain, path: path, result: result) let domain = arguments!["domain"] as? String
MyCookieManager.deleteCookie(url: url, name: name, path: path, domain: domain, result: result)
break; break;
case "deleteCookies": case "deleteCookies":
let url = arguments!["url"] as! String let url = arguments!["url"] as! String
let domain = arguments!["domain"] as! String
let path = arguments!["path"] as! String let path = arguments!["path"] as! String
MyCookieManager.deleteCookies(url: url, domain: domain, path: path, result: result) let domain = arguments!["domain"] as? String
MyCookieManager.deleteCookies(url: url, path: path, domain: domain, result: result)
break; break;
case "deleteAllCookies": case "deleteAllCookies":
MyCookieManager.deleteAllCookies(result: result) MyCookieManager.deleteAllCookies(result: result)
@ -239,25 +239,30 @@ class MyCookieManager: NSObject, FlutterPlugin {
} }
} }
public static func deleteCookie(url: String, name: String, domain: String, path: String, result: @escaping FlutterResult) { public static func deleteCookie(url: String, name: String, path: String, domain: String?, result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else { guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false) result(false)
return return
} }
var domain = domain
httpCookieStore.getAllCookies { (cookies) in httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies { for cookie in cookies {
var originURL = "" var originURL = url
if cookie.properties![.originURL] is String { if cookie.properties![.originURL] is String {
originURL = cookie.properties![.originURL] as! String originURL = cookie.properties![.originURL] as! String
} }
else if cookie.properties![.originURL] is URL { else if cookie.properties![.originURL] is URL {
originURL = (cookie.properties![.originURL] as! URL).absoluteString originURL = (cookie.properties![.originURL] as! URL).absoluteString
} }
if (!originURL.isEmpty && originURL != url) { if domain == nil, let domainUrl = URL(string: originURL) {
continue if #available(iOS 16.0, *) {
domain = domainUrl.host()
} else {
domain = domainUrl.host
}
} }
if (cookie.domain == domain || cookie.domain == ".\(domain)" || ".\(cookie.domain)" == domain) && cookie.name == name && cookie.path == path { if let domain = domain, cookie.domain == domain, cookie.name == name, cookie.path == path {
httpCookieStore.delete(cookie, completionHandler: { httpCookieStore.delete(cookie, completionHandler: {
result(true) result(true)
}) })
@ -268,25 +273,30 @@ class MyCookieManager: NSObject, FlutterPlugin {
} }
} }
public static func deleteCookies(url: String, domain: String, path: String, result: @escaping FlutterResult) { public static func deleteCookies(url: String, path: String, domain: String?, result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else { guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false) result(false)
return return
} }
var domain = domain
httpCookieStore.getAllCookies { (cookies) in httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies { for cookie in cookies {
var originURL = "" var originURL = url
if cookie.properties![.originURL] is String { if cookie.properties![.originURL] is String {
originURL = cookie.properties![.originURL] as! String originURL = cookie.properties![.originURL] as! String
} }
else if cookie.properties![.originURL] is URL{ else if cookie.properties![.originURL] is URL {
originURL = (cookie.properties![.originURL] as! URL).absoluteString originURL = (cookie.properties![.originURL] as! URL).absoluteString
} }
if (!originURL.isEmpty && originURL != url) { if domain == nil, let domainUrl = URL(string: originURL) {
continue if #available(iOS 16.0, *) {
domain = domainUrl.host()
} else {
domain = domainUrl.host
}
} }
if (cookie.domain == domain || cookie.domain == ".\(domain)" || ".\(cookie.domain)" == domain) && cookie.path == path { if let domain = domain, cookie.domain == domain, cookie.path == path {
httpCookieStore.delete(cookie, completionHandler: nil) httpCookieStore.delete(cookie, completionHandler: nil)
} }
} }

View File

@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -300,7 +299,6 @@ class CookieManager {
///Removes a cookie by its [name] for the given [url], [domain] and [path]. ///Removes a cookie by its [name] for the given [url], [domain] and [path].
/// ///
///The default value of [path] is `"/"`. ///The default value of [path] is `"/"`.
///If [domain] is empty, its default value will be the domain name of [url].
/// ///
///[iosBelow11WebViewController] is used for deleting the cookie (also session-only cookie) using JavaScript (cookie with `isHttpOnly` enabled cannot be deleted, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) ///[iosBelow11WebViewController] is used for deleting the cookie (also session-only cookie) using JavaScript (cookie with `isHttpOnly` enabled cannot be deleted, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)
///from the current context of the [WebView] managed by that controller when you need to target iOS below 11. JavaScript must be enabled in order to work. ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11. JavaScript must be enabled in order to work.
@ -311,10 +309,9 @@ class CookieManager {
Future<void> deleteCookie( Future<void> deleteCookie(
{required Uri url, {required Uri url,
required String name, required String name,
String domain = "",
String path = "/", String path = "/",
String? domain,
InAppWebViewController? iosBelow11WebViewController}) async { InAppWebViewController? iosBelow11WebViewController}) async {
if (domain.isEmpty) domain = _getDomainName(url);
assert(url.toString().isNotEmpty); assert(url.toString().isNotEmpty);
assert(name.isNotEmpty); assert(name.isNotEmpty);
@ -346,7 +343,6 @@ class CookieManager {
///Removes all cookies for the given [url], [domain] and [path]. ///Removes all cookies for the given [url], [domain] and [path].
/// ///
///The default value of [path] is `"/"`. ///The default value of [path] is `"/"`.
///If [domain] is empty, its default value will be the domain name of [url].
/// ///
///[iosBelow11WebViewController] is used for deleting the cookies (also session-only cookies) using JavaScript (cookies with `isHttpOnly` enabled cannot be deleted, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) ///[iosBelow11WebViewController] is used for deleting the cookies (also session-only cookies) using JavaScript (cookies with `isHttpOnly` enabled cannot be deleted, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)
///from the current context of the [WebView] managed by that controller when you need to target iOS below 11. JavaScript must be enabled in order to work. ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11. JavaScript must be enabled in order to work.
@ -356,10 +352,9 @@ class CookieManager {
///to delete the cookies (session-only cookies and cookies with `isHttpOnly` enabled won't be deleted!). ///to delete the cookies (session-only cookies and cookies with `isHttpOnly` enabled won't be deleted!).
Future<void> deleteCookies( Future<void> deleteCookies(
{required Uri url, {required Uri url,
String domain = "",
String path = "/", String path = "/",
String? domain,
InAppWebViewController? iosBelow11WebViewController}) async { InAppWebViewController? iosBelow11WebViewController}) async {
if (domain.isEmpty) domain = _getDomainName(url);
assert(url.toString().isNotEmpty); assert(url.toString().isNotEmpty);
@ -398,11 +393,6 @@ class CookieManager {
await _channel.invokeMethod('deleteAllCookies', args); await _channel.invokeMethod('deleteAllCookies', args);
} }
String _getDomainName(Uri url) {
String domain = url.host;
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
Future<String> _getCookieExpirationDate(int expiresDate) async { Future<String> _getCookieExpirationDate(int expiresDate) async {
var platformUtil = PlatformUtil(); var platformUtil = PlatformUtil();
var dateTime = DateTime.fromMillisecondsSinceEpoch(expiresDate).toUtc(); var dateTime = DateTime.fromMillisecondsSinceEpoch(expiresDate).toUtc();