This repository has been archived by the owner on Jan 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 314
/
Copy pathRNCookieManagerIOS.m
268 lines (241 loc) · 10.5 KB
/
RNCookieManagerIOS.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#import "RNCookieManagerIOS.h"
#if __has_include("RCTConvert.h")
#import "RCTConvert.h"
#else
#import <React/RCTConvert.h>
#endif
static NSString * const NOT_AVAILABLE_ERROR_MESSAGE = @"WebKit/WebKit-Components are only available with iOS11 and higher!";
@implementation RNCookieManagerIOS
- (instancetype)init
{
self = [super init];
if (self) {
self.formatter = [NSDateFormatter new];
[self.formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
}
return self;
}
+ (BOOL)requiresMainQueueSetup
{
return NO;
}
RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(
set:(NSDictionary *)props
useWebKit:(BOOL)useWebKit
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSString *name = [RCTConvert NSString:props[@"name"]];
NSString *value = [RCTConvert NSString:props[@"value"]];
NSString *domain = [RCTConvert NSString:props[@"domain"]];
NSString *origin = [RCTConvert NSString:props[@"origin"]];
NSString *path = [RCTConvert NSString:props[@"path"]];
NSString *version = [RCTConvert NSString:props[@"version"]];
NSDate *expiration = [RCTConvert NSDate:props[@"expiration"]];
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:name forKey:NSHTTPCookieName];
[cookieProperties setObject:value forKey:NSHTTPCookieValue];
[cookieProperties setObject:domain forKey:NSHTTPCookieDomain];
[cookieProperties setObject:origin forKey:NSHTTPCookieOriginURL];
[cookieProperties setObject:path forKey:NSHTTPCookiePath];
[cookieProperties setObject:version forKey:NSHTTPCookieVersion];
[cookieProperties setObject:expiration forKey:NSHTTPCookieExpires];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
NSLog(@"SETTING COOKIE");
NSLog(@"%@", cookie);
if (useWebKit) {
if (@available(iOS 11.0, *)) {
dispatch_async(dispatch_get_main_queue(), ^(){
WKHTTPCookieStore *cookieStore = [[WKWebsiteDataStore defaultDataStore] httpCookieStore];
[cookieStore setCookie:cookie completionHandler:nil];
resolve(nil);
});
} else {
reject(@"", NOT_AVAILABLE_ERROR_MESSAGE, nil);
}
} else {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
resolve(nil);
}
}
RCT_EXPORT_METHOD(setFromResponse:(NSURL *)url
value:(NSString *)value
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:@{@"Set-Cookie": value} forURL:url];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:url mainDocumentURL:NULL];
resolve(nil);
}
RCT_EXPORT_METHOD(getFromResponse:(NSURL *)url
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:httpResponse.allHeaderFields forURL:response.URL];
NSMutableDictionary *dics = [NSMutableDictionary dictionary];
for (int i = 0; i < cookies.count; i++) {
NSHTTPCookie *cookie = [cookies objectAtIndex:i];
[dics setObject:cookie.value forKey:cookie.name];
NSLog(@"cookie: name=%@, value=%@", cookie.name, cookie.value);
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
resolve(dics);
}];
}
-(NSString *)getDomainName:(NSURL *) url
{
NSString *separator = @".";
NSInteger maxLength = 2;
NSURLComponents *components = [[NSURLComponents alloc]initWithURL:url resolvingAgainstBaseURL:FALSE];
NSArray<NSString *> *separatedHost = [components.host componentsSeparatedByString:separator];
NSInteger count = [separatedHost count];
NSInteger endPosition = count;
NSInteger startPosition = count - maxLength;
NSMutableString *result = [[NSMutableString alloc]init];
for (NSUInteger i = startPosition; i != endPosition; i++) {
[result appendString:separator];
[result appendString:[separatedHost objectAtIndex:i]];
}
return result;
}
RCT_EXPORT_METHOD(
get:(NSURL *) url
useWebKit:(BOOL)useWebKit
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
if (useWebKit) {
if (@available(iOS 11.0, *)) {
dispatch_async(dispatch_get_main_queue(), ^(){
NSString *topLevelDomain = [self getDomainName:url];
WKHTTPCookieStore *cookieStore = [[WKWebsiteDataStore defaultDataStore] httpCookieStore];
[cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> *allCookies) {
NSMutableDictionary *cookies = [NSMutableDictionary dictionary];
for(NSHTTPCookie *currentCookie in allCookies) {
if([currentCookie.domain containsString:topLevelDomain]) {
[cookies setObject:currentCookie.value forKey:currentCookie.name];
}
}
resolve(cookies);
}];
});
} else {
reject(@"", NOT_AVAILABLE_ERROR_MESSAGE, nil);
}
} else {
NSMutableDictionary *cookies = [NSMutableDictionary dictionary];
for (NSHTTPCookie *c in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:url]) {
NSMutableDictionary *d = [NSMutableDictionary dictionary];
[d setObject:c.value forKey:@"value"];
[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"];
[cookies setObject:d forKey:c.name];
}
resolve(cookies);
}
}
RCT_EXPORT_METHOD(
clearAll:(BOOL)useWebKit
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
if (useWebKit) {
if (@available(iOS 11.0, *)) {
dispatch_async(dispatch_get_main_queue(), ^(){
WKHTTPCookieStore *cookieStore = [[WKWebsiteDataStore defaultDataStore] httpCookieStore];
[cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> *allCookies) {
for(NSHTTPCookie *currentCookie in allCookies) {
// Uses the NSHTTPCookie directly has no effect, nor deleted the cookie nor thrown an error.
// Create a new cookie with the given values and delete this one do the work.
NSMutableDictionary<NSHTTPCookiePropertyKey, id> *cookieData = [NSMutableDictionary dictionary];
[cookieData setValue:currentCookie.name forKey:NSHTTPCookieName];
[cookieData setValue:currentCookie.value forKey:NSHTTPCookieValue];
[cookieData setValue:currentCookie.domain forKey:NSHTTPCookieDomain];
[cookieData setValue:currentCookie.path forKey:NSHTTPCookiePath];
NSHTTPCookie *newCookie = [NSHTTPCookie cookieWithProperties:cookieData];
[cookieStore deleteCookie:newCookie completionHandler:^{}];
}
resolve(nil);
}];
});
} else {
reject(@"", NOT_AVAILABLE_ERROR_MESSAGE, nil);
}
} else {
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *c in cookieStorage.cookies) {
[cookieStorage deleteCookie:c];
}
resolve(nil);
}
}
RCT_EXPORT_METHOD(clearByName:(NSString *) name
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *c in cookieStorage.cookies) {
if ([[c name] isEqualToString:name]) {
[cookieStorage deleteCookie:c];
}
}
resolve(nil);
}
RCT_EXPORT_METHOD(
getAll:(BOOL)useWebKit
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
if (useWebKit) {
if (@available(iOS 11.0, *)) {
dispatch_async(dispatch_get_main_queue(), ^(){
WKHTTPCookieStore *cookieStore = [[WKWebsiteDataStore defaultDataStore] httpCookieStore];
[cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> *allCookies) {
resolve([self createCookieList: allCookies]);
}];
});
} else {
reject(@"", NOT_AVAILABLE_ERROR_MESSAGE, nil);
}
} else {
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
resolve([self createCookieList:cookieStorage.cookies]);
}
}
RCT_EXPORT_METHOD(getAll:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSMutableDictionary *cookies = [NSMutableDictionary dictionary];
for (NSHTTPCookie *c in cookieStorage.cookies) {
NSMutableDictionary *d = [NSMutableDictionary dictionary];
[d setObject:c.value forKey:@"value"];
[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"];
[cookies setObject:d forKey:c.name];
}
}
-(NSDictionary *)createCookieList:(NSArray<NSHTTPCookie *>*)cookies
{
NSMutableDictionary *cookieList = [NSMutableDictionary dictionary];
for (NSHTTPCookie *cookie in cookies) {
// NSLog(@"COOKIE: %@", cookie);
[cookieList setObject:[self createCookieData:cookie] forKey:cookie.name];
}
return cookieList;
}
-(NSDictionary *)createCookieData:(NSHTTPCookie *)cookie
{
NSMutableDictionary *cookieData = [NSMutableDictionary dictionary];
[cookieData setObject:cookie.value forKey:@"value"];
[cookieData setObject:cookie.name forKey:@"name"];
[cookieData setObject:cookie.domain forKey:@"domain"];
[cookieData setObject:cookie.path forKey:@"path"];
return cookieData;
}
@end