diff --git a/android/capacitor/src/main/assets/native-bridge.js b/android/capacitor/src/main/assets/native-bridge.js index 32db85285a..4810b4a189 100644 --- a/android/capacitor/src/main/assets/native-bridge.js +++ b/android/capacitor/src/main/assets/native-bridge.js @@ -268,11 +268,6 @@ const nativeBridge = (function (exports) { } return String(msg); }; - /** - * Safely web decode a string value (inspired by js-cookie) - * @param str The string value to decode - */ - const decode = (str) => str.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent); const platform = getPlatformId(win); if (platform == 'android' || platform == 'ios') { // patch document.cookie on Android/iOS @@ -305,7 +300,7 @@ const nativeBridge = (function (exports) { // Use prompt to synchronously get cookies. // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 const payload = { - type: 'CapacitorCookies', + type: 'CapacitorCookies.get', }; const res = prompt(JSON.stringify(payload)); return res; @@ -322,10 +317,19 @@ const nativeBridge = (function (exports) { if (null == cookieValue) { continue; } - cap.toNative('CapacitorCookies', 'setCookie', { - key: cookieKey, - value: decode(cookieValue), - }); + if (platform === 'ios') { + // Use prompt to synchronously set cookies. + // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 + const payload = { + type: 'CapacitorCookies.set', + key: cookieKey, + value: cookieValue, + }; + prompt(JSON.stringify(payload)); + } + else if (typeof win.CapacitorCookiesAndroidInterface !== 'undefined') { + win.CapacitorCookiesAndroidInterface.setCookie(cookieKey, cookieValue); + } } }, }); diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java index 4d3175980f..e1989eac57 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java @@ -1,12 +1,7 @@ package com.getcapacitor.plugin; -import android.app.Activity; -import android.content.SharedPreferences; -import android.util.Log; import android.webkit.JavascriptInterface; import androidx.annotation.Nullable; -import com.getcapacitor.CapConfig; -import com.getcapacitor.JSObject; import com.getcapacitor.Plugin; import com.getcapacitor.PluginCall; import com.getcapacitor.PluginConfig; @@ -87,6 +82,15 @@ public String getCookies() { return ""; } + @JavascriptInterface + public void setCookie(String key, String value) { + String url = getServerUrl(null); + + if (!url.isEmpty()) { + cookieManager.setCookie(url, key, value); + } + } + @PluginMethod public void setCookie(PluginCall call) { String key = call.getString("key"); diff --git a/core/native-bridge.ts b/core/native-bridge.ts index 3d12249521..1660880276 100644 --- a/core/native-bridge.ts +++ b/core/native-bridge.ts @@ -288,13 +288,6 @@ const initBridge = (w: any): void => { return String(msg); }; - /** - * Safely web decode a string value (inspired by js-cookie) - * @param str The string value to decode - */ - const decode = (str: string): string => - str.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent); - const platform = getPlatformId(win); if (platform == 'android' || platform == 'ios') { @@ -334,7 +327,7 @@ const initBridge = (w: any): void => { // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 const payload = { - type: 'CapacitorCookies', + type: 'CapacitorCookies.get', }; const res = prompt(JSON.stringify(payload)); @@ -355,10 +348,25 @@ const initBridge = (w: any): void => { continue; } - cap.toNative('CapacitorCookies', 'setCookie', { - key: cookieKey, - value: decode(cookieValue), - }); + if (platform === 'ios') { + // Use prompt to synchronously set cookies. + // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 + + const payload = { + type: 'CapacitorCookies.set', + key: cookieKey, + value: cookieValue, + }; + + prompt(JSON.stringify(payload)); + } else if ( + typeof win.CapacitorCookiesAndroidInterface !== 'undefined' + ) { + win.CapacitorCookiesAndroidInterface.setCookie( + cookieKey, + cookieValue, + ); + } } }, }); diff --git a/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift b/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift index 9249ebd67f..e7094d7146 100644 --- a/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift +++ b/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift @@ -31,6 +31,14 @@ public class CapacitorCookieManager { return value.removingPercentEncoding! } + public func setCookie(_ key: String, _ value: String) { + let url = getServerUrl()! + let jar = HTTPCookieStorage.shared + let field = ["Set-Cookie": "\(key)=\(value)"] + let cookies = HTTPCookie.cookies(withResponseHeaderFields: field, for: url) + jar.setCookies(cookies, for: url, mainDocumentURL: url) + } + public func setCookie(_ url: URL, _ key: String, _ value: String) { let jar = HTTPCookieStorage.shared let field = ["Set-Cookie": "\(key)=\(value)"] diff --git a/ios/Capacitor/Capacitor/WebViewDelegationHandler.swift b/ios/Capacitor/Capacitor/WebViewDelegationHandler.swift index cff1b8d7cf..f0e5256b93 100644 --- a/ios/Capacitor/Capacitor/WebViewDelegationHandler.swift +++ b/ios/Capacitor/Capacitor/WebViewDelegationHandler.swift @@ -250,10 +250,19 @@ internal class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDel if let payload = try JSONSerialization.jsonObject(with: dataFromString, options: .fragmentsAllowed) as? [String: AnyObject] { let type = payload["type"] as? String - if type == "CapacitorCookies" { + if type == "CapacitorCookies.get" { completionHandler(CapacitorCookieManager(bridge!.config).getCookies()) // Don't present prompt return + } else if type == "CapacitorCookies.set" { + // swiftlint:disable force_cast + let key = payload["key"] as! String + let value = payload["value"] as! String + CapacitorCookieManager(bridge!.config).setCookie(key, value) + completionHandler("") + // swiftlint:enable force_cast + // Don't present prompt + return } else if type == "CapacitorCookies.isEnabled" { let pluginConfig = bridge!.config.getPluginConfig("CapacitorCookies") completionHandler(String(pluginConfig.getBoolean("enabled", false))) diff --git a/ios/Capacitor/Capacitor/assets/native-bridge.js b/ios/Capacitor/Capacitor/assets/native-bridge.js index 32db85285a..4810b4a189 100644 --- a/ios/Capacitor/Capacitor/assets/native-bridge.js +++ b/ios/Capacitor/Capacitor/assets/native-bridge.js @@ -268,11 +268,6 @@ const nativeBridge = (function (exports) { } return String(msg); }; - /** - * Safely web decode a string value (inspired by js-cookie) - * @param str The string value to decode - */ - const decode = (str) => str.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent); const platform = getPlatformId(win); if (platform == 'android' || platform == 'ios') { // patch document.cookie on Android/iOS @@ -305,7 +300,7 @@ const nativeBridge = (function (exports) { // Use prompt to synchronously get cookies. // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 const payload = { - type: 'CapacitorCookies', + type: 'CapacitorCookies.get', }; const res = prompt(JSON.stringify(payload)); return res; @@ -322,10 +317,19 @@ const nativeBridge = (function (exports) { if (null == cookieValue) { continue; } - cap.toNative('CapacitorCookies', 'setCookie', { - key: cookieKey, - value: decode(cookieValue), - }); + if (platform === 'ios') { + // Use prompt to synchronously set cookies. + // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323 + const payload = { + type: 'CapacitorCookies.set', + key: cookieKey, + value: cookieValue, + }; + prompt(JSON.stringify(payload)); + } + else if (typeof win.CapacitorCookiesAndroidInterface !== 'undefined') { + win.CapacitorCookiesAndroidInterface.setCookie(cookieKey, cookieValue); + } } }, });