capacitor icon indicating copy to clipboard operation
capacitor copied to clipboard

bug: For Android, receiving a cookie from a server with domain set results in document.cookie not being updated

Open nickredding opened this issue 2 years ago • 1 comments

Bug Report

Capacitor Version

   Capacitor Doctor

Latest Dependencies:

  @capacitor/cli: 5.3.0
  @capacitor/core: 5.3.0
  @capacitor/android: 5.3.0
  @capacitor/ios: 5.3.0

Installed Dependencies:

  @capacitor/cli: 5.3.0
  @capacitor/core: 5.3.0
  @capacitor/ios: 5.3.0
  @capacitor/android: 5.3.0

Platform(s)

Android

Current Behavior

When processing a Set-Cookie header from a server, if domain is set in the cookie data the cookie is not entered into document.cookie

Expected Behavior

The cookie should be entered into document.cookie as well as set against the domain

Code Reproduction

See https://github.com/nickredding/bug6792 which has been extended to demonstrate this problem.

Other Technical Details

This problem does not arise on iOS, where the cookie is set properly.

nickredding avatar Sep 08 '23 19:09 nickredding

The fix is to modify put in CapacitorCookieManager as follows

@Override
public void put(URI uri, Map<String, List<String>> responseHeaders) {
    // make sure our args are valid
    if ((uri == null) || (responseHeaders == null)) return;

    // go over the headers
    for (String headerKey : responseHeaders.keySet()) {
        // ignore headers which aren't cookie related
        if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;

        // process each of the headers
        for (String headerValue : Objects.requireNonNull(responseHeaders.get(headerKey))) {
            try {
                // Set at the requested server url
                setCookie(uri.toString(), headerValue);

                // Set at the defined domain in the response or at default capacitor hosted url
                // fixed to set cookie at default capacitor hosted url if domain is supplied
                String domain = getDomainFromCookieString(headerValue);
                String localValue = headerValue;
                setCookie(domain, headerValue);
                if (domain != null) {
                    localValue = localValue.replace(domain, this.localUrl.replaceFirst("^[a-z]*://", ""));
                    setCookie(null, localValue);
                }
            } catch (Exception ignored) {}
        }
    }
}

nickredding avatar Sep 10 '23 17:09 nickredding