Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: adds setCookie/deleteCookie #15

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 138 additions & 26 deletions src/ios/WebviewProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ @interface WebviewProxy : CDVPlugin {

@property (nonatomic) NSMutableArray* stoppedTasks;

- (void)clearCookie:(CDVInvokedUrlCommand*)command;
- (void)clearCookies:(CDVInvokedUrlCommand*)command;
- (void)setCookie:(CDVInvokedUrlCommand*)command;
- (void)deleteCookie:(CDVInvokedUrlCommand*)command;

@end

Expand All @@ -22,7 +24,6 @@ - (void) pluginInitialize {
- (BOOL) overrideSchemeTask: (id <WKURLSchemeTask>)urlSchemeTask {
NSString * startPath = @"";
NSURL * url = urlSchemeTask.request.URL;
NSDictionary * header = urlSchemeTask.request.allHTTPHeaderFields;
NSMutableString * stringToLoad = [NSMutableString string];
[stringToLoad appendString:url.path];
NSString * method = urlSchemeTask.request.HTTPMethod;
Expand All @@ -35,17 +36,30 @@ - (BOOL) overrideSchemeTask: (id <WKURLSchemeTask>)urlSchemeTask {
} startPath = [stringToLoad stringByReplacingOccurrencesOfString:@"/_http_proxy_" withString:@"http://"];
startPath = [startPath stringByReplacingOccurrencesOfString:@"/_https_proxy_" withString:@"https://"];
NSURL * requestUrl = [NSURL URLWithString:startPath];
WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
// WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
// WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
// create cookies for the requestUrl and merge them with the existing http header fields
NSArray *requestCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:requestUrl];
NSDictionary * cookieHeaders = [NSHTTPCookie requestHeaderFieldsWithCookies:requestCookies];
NSMutableDictionary * allHTTPHeaderFields = [cookieHeaders mutableCopy];
[allHTTPHeaderFields addEntriesFromDictionary:urlSchemeTask.request.allHTTPHeaderFields];
// we're taking care of cookies
[request setHTTPShouldHandleCookies:NO];

[request setHTTPMethod:method];
[request setURL:requestUrl];
if (body) {
[request setHTTPBody:body];
}
[request setAllHTTPHeaderFields:header];
[request setHTTPShouldHandleCookies:YES];
[request setAllHTTPHeaderFields:allHTTPHeaderFields];
[request setTimeoutInterval:1800];
NSHTTPCookieStorage *storage1 = [NSHTTPCookieStorage sharedHTTPCookieStorage];

for (NSHTTPCookie *cookie in storage1.cookies) {
NSLog(@"read cookie %@:%@:%@", cookie.domain, cookie.name, cookie.value);
}

[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error && (self.stoppedTasks == nil || ![self.stoppedTasks containsObject:urlSchemeTask])) {
Expand All @@ -63,17 +77,18 @@ - (BOOL) overrideSchemeTask: (id <WKURLSchemeTask>)urlSchemeTask {
if(httpResponse) {
NSArray* cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[httpResponse allHeaderFields] forURL:response.URL];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:httpResponse.URL mainDocumentURL:nil];
cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
// cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];

for (NSHTTPCookie* c in cookies)
{
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//running in background thread is necessary because setCookie otherwise fails
dispatch_async(dispatch_get_main_queue(), ^(void){
[cookieStore setCookie:c completionHandler:nil];
});
});
};
// for (NSHTTPCookie* c in cookies)
menelike marked this conversation as resolved.
Show resolved Hide resolved
// {
// dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
// //running in background thread is necessary because setCookie otherwise fails
// dispatch_async(dispatch_get_main_queue(), ^(void){
// [cookieStore setCookie:c completionHandler:nil];
// NSLog(@"set cookie %@:%@:%@", c.domain, c.name, c.value);
// });
// });
// };
}

// Do not use urlSchemeTask if it has been closed in stopURLSchemeTask. Otherwise the app will crash.
Expand Down Expand Up @@ -103,19 +118,116 @@ - (void) stopSchemeTask: (id <WKURLSchemeTask>)urlSchemeTask {
[self.stoppedTasks addObject:urlSchemeTask];
}

- (void) clearCookie:(CDVInvokedUrlCommand*)command {
CDVPluginResult* pluginResult = nil;
- (void)deleteCookie:(CDVInvokedUrlCommand *)command {
NSMutableDictionary* options = [command.arguments objectAtIndex:0];

if ([options objectForKey:@"domain"] == nil || [options objectForKey:@"name"] == nil) {
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
return;
}

@try {
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in storage.cookies) {
bool domainMatch = [cookie.domain isEqualToString: [options objectForKey:@"domain"]];
bool nameMatch =[cookie.name isEqualToString: [options objectForKey:@"name"]];

if (domainMatch && nameMatch && (([options objectForKey:@"path"] != nil && [cookie.path isEqualToString: [options objectForKey:@"path"]]) || [options objectForKey:@"path"] == nil)) {
NSLog(@"deleteCookie(): removed cookie %@:%@:%@ from sharedHTTPCookieStorage", cookie.domain, cookie.name, cookie.value);
[storage deleteCookie:cookie];
}
}

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@catch (NSException *exception) {
NSLog(@"WebViewProxy deleteCookie() exception: %@", exception.debugDescription);

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:exception.reason];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

}

WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
[cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> * cookies) {
for (NSHTTPCookie* _c in cookies)
{
[cookieStore deleteCookie:_c completionHandler:nil];
};
}];
- (void)setCookie:(CDVInvokedUrlCommand *)command {
@try {
NSMutableDictionary* options = [command.arguments objectAtIndex:0];

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
if ([options objectForKey:@"comment"] != nil) [cookieProperties setObject:[options objectForKey:@"comment"] forKey:NSHTTPCookieComment];
if ([options objectForKey:@"commentUrl"] != nil)[cookieProperties setObject:[options objectForKey:@"commentUrl"] forKey:NSHTTPCookieCommentURL];
if ([options objectForKey:@"discard"] != nil) [cookieProperties setObject:[options objectForKey:@"discard"] forKey:NSHTTPCookieDiscard];
if ([options objectForKey:@"domain"] != nil) [cookieProperties setObject:[options objectForKey:@"domain"] forKey:NSHTTPCookieDomain]; // required
if ([options objectForKey:@"expires"] != nil) [cookieProperties setObject:[options objectForKey:@"expires"] forKey:NSHTTPCookieExpires];
if ([options objectForKey:@"maximumAge"] != nil) [cookieProperties setObject:[options objectForKey:@"maximumAge"] forKey:NSHTTPCookieMaximumAge];
if ([options objectForKey:@"name"] != nil) [cookieProperties setObject:[options objectForKey:@"name"] forKey:NSHTTPCookieName]; // required
if ([options objectForKey:@"domain"] != nil) [cookieProperties setObject:[options objectForKey:@"domain"] forKey:NSHTTPCookieOriginURL]; // reuse required domain
if ([options objectForKey:@"path"] != nil) [cookieProperties setObject:[options objectForKey:@"path"] forKey:NSHTTPCookiePath]; // required
if ([options objectForKey:@"port"] != nil) [cookieProperties setObject:[options objectForKey:@"port"] forKey:NSHTTPCookiePort];
if (@available(iOS 13.0, *)) {
if ([options objectForKey:@"sameSitePolicy"] != nil) [cookieProperties setObject:[options objectForKey:@"sameSitePolicy"] forKey:NSHTTPCookieSameSitePolicy];
}
if ([options objectForKey:@"secure"] != nil) [cookieProperties setObject:[options objectForKey:@"secure"] forKey:NSHTTPCookieSecure];
if ([options objectForKey:@"value"] != nil) [cookieProperties setObject:[options objectForKey:@"value"] forKey:NSHTTPCookieValue]; // required
if ([options objectForKey:@"version"] != nil) [cookieProperties setObject:[options objectForKey:@"version"] forKey:NSHTTPCookieVersion];

NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
NSLog(@"setCookie(): %@:%@:%@", cookie.domain, cookie.name, cookie.value);
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
[storage setCookie:cookie];

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@catch (NSException *exception) {
NSLog(@"WebViewProxy setCookie() exception: %@", exception.debugDescription);

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:exception.reason];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
}

- (void) clearCookies:(CDVInvokedUrlCommand*)command {
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];


if (storage.cookies.count > 0) {
for (NSHTTPCookie *cookie in storage.cookies) {
NSLog(@"clearCookies(): removed cookie %@:%@:%@", cookie.domain, cookie.name, cookie.value);
[storage deleteCookie:cookie];
}
NSLog(@"clearCookies(): all cookies cleared");

} else {
NSLog(@"clearCookies(): no cookies found to be cleared");
}


CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];

// WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
menelike marked this conversation as resolved.
Show resolved Hide resolved
// WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
//
// [cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> * cookies) {
// if ([cookies count] == 0) {
// NSLog(@"no cookies to be removed");
// }
// dispatch_group_t group = dispatch_group_create();
// for (NSHTTPCookie* _c in cookies)
// {
// dispatch_group_enter(group);
// [cookieStore deleteCookie:_c completionHandler:^{
// NSLog(@"removed cookie %@:%@:%@ from defaultDataStore", _c.domain, _c.name, _c.value);
// dispatch_group_leave(group);
// }];
// };
// dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
// });
// }];
}

@end
14 changes: 11 additions & 3 deletions www/WebviewProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ WebviewProxy.prototype.convertProxyUrl = function (path) {
return path;
}

WebviewProxy.prototype.clearCookie = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "WebviewProxy", "clearCookie", []);
WebviewProxy.prototype.clearCookies = function (successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "WebviewProxy", "clearCookies", []);
}

module.exports = new WebviewProxy();
WebviewProxy.prototype.deleteCookie = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "WebviewProxy", "deleteCookie", [options]);
}

WebviewProxy.prototype.setCookie = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "WebviewProxy", "setCookie", [options]);
}

module.exports = new WebviewProxy();