diff --git a/android/src/main/java/com/psykar/cookiemanager/CookieManagerModule.java b/android/src/main/java/com/psykar/cookiemanager/CookieManagerModule.java index d60361f6..12ae2f07 100644 --- a/android/src/main/java/com/psykar/cookiemanager/CookieManagerModule.java +++ b/android/src/main/java/com/psykar/cookiemanager/CookieManagerModule.java @@ -12,14 +12,27 @@ import java.io.IOException; import java.net.URISyntaxException; +import java.text.ParseException; import java.net.URI; +import java.text.DateFormat; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Date; +import java.text.SimpleDateFormat; public class CookieManagerModule extends ReactContextBaseJavaModule { + private static final String COOKIE_HEADER = "Cookie"; + private static final String VERSION_ZERO_HEADER = "Set-cookie"; + + private static final String COOKIE_DOMAIN_PROPERTY = "Domain"; + private static final String COOKIE_PATH_PROPERTY = "Path"; + private static final String COOKIE_EXPIRES_PROPERTY = "Expires"; + + private static final String ISO_DATE_FORMAT_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + private ForwardingCookieHandler cookieHandler; public CookieManagerModule(ReactApplicationContext context) { @@ -33,7 +46,32 @@ public String getName() { @ReactMethod public void set(ReadableMap cookie, boolean useWebKit, final Promise promise) throws Exception { - throw new Exception("Cannot call on android, try setFromResponse"); + try { + String cookieName = this.confirmCookieProperty( "name", cookie, true ); + String cookieValue = this.confirmCookieProperty( "value", cookie, true ); + String cookieOrigin = this.confirmCookieProperty( "origin", cookie, true ); + String cookieDomain = this.confirmCookieProperty( "domain", cookie, false ); + String cookiePath = this.confirmCookieProperty( "path", cookie, false ); + String cookieVersion = this.confirmCookieProperty( "version", cookie, false ); + String cookieExpiration = this.confirmCookieProperty( "expiration", cookie, false ); + + String cookieString = cookieName + '=' + cookieValue + ';'; + + if( !cookieDomain.isEmpty() ) { + cookieString += ' ' + COOKIE_DOMAIN_PROPERTY + '=' + cookieDomain + ';'; + } + if( !cookiePath.isEmpty() ) { + cookieString += ' ' + COOKIE_PATH_PROPERTY + '=' + cookiePath + ';'; + } + if( !cookieExpiration.isEmpty() ) { + cookieString += ' ' + COOKIE_EXPIRES_PROPERTY + '=' + this.convertToUTC( cookieExpiration ) + ';'; + } + + this.setCookie( cookieOrigin, cookieString ); + promise.resolve( true ); + } catch( Exception e ) { + promise.reject(e); + } } @ReactMethod @@ -73,7 +111,7 @@ public void get(String url, boolean useWebKit, Promise promise) throws URISyntax for (int i = 0; i < cookies.length; i++) { String[] cookie = cookies[i].split("=", 2); if (cookie.length > 1) { - map.putString(cookie[0].trim(), cookie[1]); + map.putString(cookie[0].trim(), cookie[1]); } } } @@ -88,4 +126,32 @@ public void invoke(Object... args) { } }); } + + private void setCookie( String url, String value ) throws URISyntaxException, IOException { + URI uri = new URI(url); + Map> cookieMap = new HashMap<>(); + cookieMap.put( VERSION_ZERO_HEADER, Collections.singletonList(value) ); + this.cookieHandler.put( uri, cookieMap ); + } + + private String confirmCookieProperty( String propName, ReadableMap cookieObj, Boolean isNecessary ) throws Exception { + String propValue = cookieObj.hasKey( propName ) ? cookieObj.getString( propName ) : ""; + + if( propValue != null && !propValue.isEmpty() ) { + return propValue; + } else { + if( isNecessary ) { + throw new Exception( propName + " property of cookie obj must have a value" ); + } else { + return ""; + } + } + } + + private String convertToUTC(String timestamp) throws ParseException, Exception { + SimpleDateFormat parser = new SimpleDateFormat( ISO_DATE_FORMAT_PATTERN ); + Date parsedDate = parser.parse(timestamp); + SimpleDateFormat utcFormatter = new SimpleDateFormat( "E, dd MMM YYYY HH:mm:ss" ); + return utcFormatter.format(parsedDate) + " GMT"; + } } diff --git a/ios/RNCookieManagerIOS/RNCookieManagerIOS.m b/ios/RNCookieManagerIOS/RNCookieManagerIOS.m index 47609f69..53d848b4 100644 --- a/ios/RNCookieManagerIOS/RNCookieManagerIOS.m +++ b/ios/RNCookieManagerIOS/RNCookieManagerIOS.m @@ -152,7 +152,11 @@ -(NSString *)getDomainName:(NSURL *) url [d setObject:c.name forKey:@"name"]; [d setObject:c.domain forKey:@"domain"]; [d setObject:c.path forKey:@"path"]; - [d setObject:[self.formatter stringFromDate:c.expiresDate] forKey:@"expiresDate"]; + if( c.expiresDate == nil || c.expiresDate == (id)[NSNull null] ) { + [d setObject:@"" forKey:@"expiresDate"]; + } else { + [d setObject:[self.formatter stringFromDate:c.expiresDate] forKey:@"expiresDate"]; + } [cookies setObject:d forKey:c.name]; } resolve(cookies); @@ -240,7 +244,11 @@ -(NSString *)getDomainName:(NSURL *) url [d setObject:c.name forKey:@"name"]; [d setObject:c.domain forKey:@"domain"]; [d setObject:c.path forKey:@"path"]; - [d setObject:[self.formatter stringFromDate:c.expiresDate] forKey:@"expiresDate"]; + if( c.expiresDate == nil || c.expiresDate == (id)[NSNull null] ) { + [d setObject:@"" forKey:@"expiresDate"]; + } else { + [d setObject:[self.formatter stringFromDate:c.expiresDate] forKey:@"expiresDate"]; + } [cookies setObject:d forKey:c.name]; } }