6
6
7
7
#import < Foundation/Foundation.h>
8
8
#import < UIKit/UIKit.h>
9
+ #import < objc/runtime.h>
9
10
10
11
#import " OAuthManager.h"
11
12
#import " DCTAuth.h"
16
17
#import " OAuth2Client.h"
17
18
18
19
@interface OAuthManager ()
19
- @property (nonatomic ) NSArray *pendingClients;
20
- @property BOOL pendingAuthentication;
20
+ @property (nonatomic ) NSArray *pendingClients;
21
+ @property BOOL pendingAuthentication;
21
22
@end
22
23
23
24
@implementation OAuthManager
@@ -33,7 +34,7 @@ @implementation OAuthManager
33
34
// Run on a different thread
34
35
- (dispatch_queue_t )methodQueue
35
36
{
36
- return dispatch_queue_create (" io.fullstack.oauth" , DISPATCH_QUEUE_SERIAL);
37
+ return dispatch_queue_create (" io.fullstack.oauth" , DISPATCH_QUEUE_SERIAL);
37
38
}
38
39
39
40
+ (instancetype )sharedManager {
@@ -58,7 +59,7 @@ - (instancetype) init {
58
59
selector: @selector (didBecomeActive: )
59
60
name: UIApplicationDidBecomeActiveNotification
60
61
object: nil ];
61
-
62
+
62
63
}
63
64
return self;
64
65
}
@@ -108,7 +109,7 @@ + (BOOL)handleOpenUrl:(UIApplication *)application openURL:(NSURL *)url
108
109
{
109
110
OAuthManager *manager = [OAuthManager sharedManager ];
110
111
NSString *strUrl = [manager stringHost: url];
111
-
112
+
112
113
if ([manager.callbackUrls indexOfObject: strUrl] != NSNotFound ) {
113
114
return [DCTAuth handleURL: url];
114
115
}
@@ -193,7 +194,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
193
194
#pragma mark OAuth
194
195
195
196
RCT_EXPORT_METHOD (getSavedAccounts:(NSDictionary *) opts
196
- callback:(RCTResponseSenderBlock) callback)
197
+ callback:(RCTResponseSenderBlock) callback)
197
198
{
198
199
OAuthManager *manager = [OAuthManager sharedManager ];
199
200
DCTAuthAccountStore *store = [manager accountStore ];
@@ -263,7 +264,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
263
264
[store deleteAccount: existingAccount];
264
265
callback (@[[NSNull null ], @{
265
266
@" status" : @" ok"
266
- }]);
267
+ }]);
267
268
} else {
268
269
NSDictionary *resp = @{
269
270
@" status" : @" error" ,
@@ -300,7 +301,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
300
301
[store deleteAccount: existingAccount];
301
302
}
302
303
}
303
-
304
+
304
305
NSString *callbackUrl;
305
306
NSURL *storedCallbackUrl = [cfg objectForKey: @" callback_url" ];
306
307
@@ -330,11 +331,11 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
330
331
@" msg" : @" Unknown provider"
331
332
}]);
332
333
}
333
-
334
+
334
335
// Store pending client
335
336
336
337
[manager addPending: client];
337
- _pendingAuthentication = YES ;
338
+ _pendingAuthentication = YES ;
338
339
339
340
[client authorizeWithUrl: providerName
340
341
url: callbackUrl
@@ -364,30 +365,30 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
364
365
opts:(NSDictionary *) opts
365
366
callback:(RCTResponseSenderBlock)callback)
366
367
{
367
- OAuthManager *manager = [OAuthManager sharedManager ];
368
- NSMutableDictionary *cfg = [[manager getConfigForProvider: providerName] mutableCopy ];
368
+ OAuthManager *manager = [OAuthManager sharedManager ];
369
+ NSMutableDictionary *cfg = [[manager getConfigForProvider: providerName] mutableCopy ];
369
370
370
371
DCTAuthAccount *existingAccount = [manager accountForProvider: providerName];
371
372
if (existingAccount == nil ) {
372
373
NSDictionary *errResp = @{
373
- @" status" : @" error" ,
374
- @" msg" : [NSString stringWithFormat: @" No account found for %@ " , providerName]
375
- };
374
+ @" status" : @" error" ,
375
+ @" msg" : [NSString stringWithFormat: @" No account found for %@ " , providerName]
376
+ };
376
377
callback (@[errResp]);
377
378
return ;
378
379
}
379
-
380
- // If we have the http in the string, use it as the URL, otherwise create one
381
- // with the configuration
382
- NSURL *apiUrl;
383
- if ([urlOrPath hasPrefix: @" http" ]) {
384
- apiUrl = [NSURL URLWithString: urlOrPath];
385
- } else {
386
- NSURL *apiHost = [cfg objectForKey: @" api_url" ];
387
- apiUrl = [NSURL URLWithString: [[apiHost absoluteString ] stringByAppendingString: urlOrPath]];
388
- }
389
-
390
- // If there are params
380
+
381
+ // If we have the http in the string, use it as the URL, otherwise create one
382
+ // with the configuration
383
+ NSURL *apiUrl;
384
+ if ([urlOrPath hasPrefix: @" http" ]) {
385
+ apiUrl = [NSURL URLWithString: urlOrPath];
386
+ } else {
387
+ NSURL *apiHost = [cfg objectForKey: @" api_url" ];
388
+ apiUrl = [NSURL URLWithString: [[apiHost absoluteString ] stringByAppendingString: urlOrPath]];
389
+ }
390
+
391
+ // If there are params
391
392
NSMutableArray *items = [NSMutableArray array ];
392
393
NSDictionary *params = [opts objectForKey: @" params" ];
393
394
if (params != nil ) {
@@ -402,11 +403,11 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
402
403
DCTAuthRequestMethod method = [manager getRequestMethodByString: methodStr];
403
404
404
405
DCTAuthRequest *request =
405
- [[DCTAuthRequest alloc ]
406
- initWithRequestMethod: method
407
- URL: apiUrl
408
- items: items];
409
-
406
+ [[DCTAuthRequest alloc ]
407
+ initWithRequestMethod: method
408
+ URL: apiUrl
409
+ items: items];
410
+
410
411
NSDictionary *body = [opts objectForKey: @" body" ];
411
412
if (body != nil ) {
412
413
for (NSString *key in body) {
@@ -426,7 +427,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
426
427
}
427
428
request.HTTPHeaders = existingHeaders;
428
429
}
429
-
430
+
430
431
[request performRequestWithHandler: ^(DCTAuthResponse *response, NSError *error) {
431
432
if (error != nil ) {
432
433
NSDictionary *errorDict = @{
@@ -503,6 +504,7 @@ - (DCTAuthRequestMethod) getRequestMethodByString:(NSString *) method
503
504
- (NSDictionary *) getAccountResponse : (DCTAuthAccount *) account
504
505
cfg : (NSDictionary *)cfg
505
506
{
507
+ NSArray *ignoredCredentialProperties = @[@" superclass" , @" hash" , @" description" , @" debugDescription" ];
506
508
NSString *version = [cfg valueForKey: @" auth_version" ];
507
509
NSMutableDictionary *accountResponse = [@{
508
510
@" authorized" : @(account.authorized ),
@@ -521,23 +523,51 @@ - (NSDictionary *) getAccountResponse:(DCTAuthAccount *) account
521
523
} else if ([version isEqualToString: @" 2.0" ]) {
522
524
DCTOAuth2Credential *credential = account.credential ;
523
525
if (credential != nil ) {
524
- NSMutableDictionary *cred = [@{
525
- @" access_token" : credential.accessToken ,
526
- @" type" : @(credential.type )
527
- } mutableCopy];
528
- if (credential.refreshToken != nil ) {
529
- [cred setValue: credential.refreshToken forKey: @" refresh_token" ];
530
- }
526
+
527
+ NSDictionary *cred = [self dictionaryForCredentialKeys: credential];
531
528
[accountResponse setObject: cred forKey: @" credentials" ];
532
529
}
533
530
}
534
531
[accountResponse setValue: [account identifier ] forKey: @" identifier" ];
535
532
if (account.userInfo != nil ) {
536
- [accountResponse setObject: [account userInfo ] forKey: @" user_info" ];
537
- }
533
+ [accountResponse setObject: [account userInfo ] forKey: @" user_info" ];
534
+ }
538
535
return accountResponse;
539
536
}
540
537
538
+ - (NSDictionary *) dictionaryForCredentialKeys : (NSObject *) credential
539
+ {
540
+ NSArray *ignoredCredentialProperties = @[@" superclass" , @" hash" , @" description" , @" debugDescription" ];
541
+ unsigned int count = 0 ;
542
+ NSMutableDictionary *cred = [NSMutableDictionary new ];
543
+ objc_property_t *properties = class_copyPropertyList ([credential class ], &count);
544
+
545
+ for (int i = 0 ; i < count; i++) {
546
+
547
+ NSString *key = [NSString stringWithUTF8String: property_getName (properties[i])];
548
+ if ([ignoredCredentialProperties containsObject: key]) {
549
+ NSLog (@" Ignoring credentials key: %@ " , key);
550
+ } else {
551
+ id value = [credential valueForKey: key];
552
+
553
+ NSLog (@" key: %@ = %@ " , key, value);
554
+ if (value == nil ) {
555
+
556
+ } else if ([value isKindOfClass: [NSNumber class ]]
557
+ || [value isKindOfClass: [NSString class ]]
558
+ || [value isKindOfClass: [NSDictionary class ]] || [value isKindOfClass: [NSMutableArray class ]]) {
559
+ // TODO: extend to other types
560
+ [cred setObject: value forKey: key];
561
+ } else if ([value isKindOfClass: [NSObject class ]]) {
562
+ [cred setObject: [value dictionary ] forKey: key];
563
+ } else {
564
+ NSLog (@" Invalid type for %@ (%@ )" , NSStringFromClass ([self class ]), key);
565
+ }
566
+ }
567
+ }
568
+ return cred;
569
+ }
570
+
541
571
- (void ) clearPending
542
572
{
543
573
OAuthManager *manager = [OAuthManager sharedManager ];
0 commit comments