66
77#import < Foundation/Foundation.h>
88#import < UIKit/UIKit.h>
9+ #import < objc/runtime.h>
910
1011#import " OAuthManager.h"
1112#import " DCTAuth.h"
1617#import " OAuth2Client.h"
1718
1819@interface OAuthManager ()
19- @property (nonatomic ) NSArray *pendingClients;
20- @property BOOL pendingAuthentication;
20+ @property (nonatomic ) NSArray *pendingClients;
21+ @property BOOL pendingAuthentication;
2122@end
2223
2324@implementation OAuthManager
@@ -33,7 +34,7 @@ @implementation OAuthManager
3334// Run on a different thread
3435- (dispatch_queue_t )methodQueue
3536{
36- return dispatch_queue_create (" io.fullstack.oauth" , DISPATCH_QUEUE_SERIAL);
37+ return dispatch_queue_create (" io.fullstack.oauth" , DISPATCH_QUEUE_SERIAL);
3738}
3839
3940+ (instancetype )sharedManager {
@@ -58,7 +59,7 @@ - (instancetype) init {
5859 selector: @selector (didBecomeActive: )
5960 name: UIApplicationDidBecomeActiveNotification
6061 object: nil ];
61-
62+
6263 }
6364 return self;
6465}
@@ -108,7 +109,7 @@ + (BOOL)handleOpenUrl:(UIApplication *)application openURL:(NSURL *)url
108109{
109110 OAuthManager *manager = [OAuthManager sharedManager ];
110111 NSString *strUrl = [manager stringHost: url];
111-
112+
112113 if ([manager.callbackUrls indexOfObject: strUrl] != NSNotFound ) {
113114 return [DCTAuth handleURL: url];
114115 }
@@ -193,7 +194,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
193194#pragma mark OAuth
194195
195196RCT_EXPORT_METHOD (getSavedAccounts:(NSDictionary *) opts
196- callback:(RCTResponseSenderBlock) callback)
197+ callback:(RCTResponseSenderBlock) callback)
197198{
198199 OAuthManager *manager = [OAuthManager sharedManager ];
199200 DCTAuthAccountStore *store = [manager accountStore ];
@@ -263,7 +264,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
263264 [store deleteAccount: existingAccount];
264265 callback (@[[NSNull null ], @{
265266 @" status" : @" ok"
266- }]);
267+ }]);
267268 } else {
268269 NSDictionary *resp = @{
269270 @" status" : @" error" ,
@@ -300,7 +301,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
300301 [store deleteAccount: existingAccount];
301302 }
302303 }
303-
304+
304305 NSString *callbackUrl;
305306 NSURL *storedCallbackUrl = [cfg objectForKey: @" callback_url" ];
306307
@@ -330,11 +331,11 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
330331 @" msg" : @" Unknown provider"
331332 }]);
332333 }
333-
334+
334335 // Store pending client
335336
336337 [manager addPending: client];
337- _pendingAuthentication = YES ;
338+ _pendingAuthentication = YES ;
338339
339340 [client authorizeWithUrl: providerName
340341 url: callbackUrl
@@ -364,30 +365,30 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
364365 opts:(NSDictionary *) opts
365366 callback:(RCTResponseSenderBlock)callback)
366367{
367- OAuthManager *manager = [OAuthManager sharedManager ];
368- NSMutableDictionary *cfg = [[manager getConfigForProvider: providerName] mutableCopy ];
368+ OAuthManager *manager = [OAuthManager sharedManager ];
369+ NSMutableDictionary *cfg = [[manager getConfigForProvider: providerName] mutableCopy ];
369370
370371 DCTAuthAccount *existingAccount = [manager accountForProvider: providerName];
371372 if (existingAccount == nil ) {
372373 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+ };
376377 callback (@[errResp]);
377378 return ;
378379 }
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
391392 NSMutableArray *items = [NSMutableArray array ];
392393 NSDictionary *params = [opts objectForKey: @" params" ];
393394 if (params != nil ) {
@@ -402,11 +403,11 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
402403 DCTAuthRequestMethod method = [manager getRequestMethodByString: methodStr];
403404
404405 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+
410411 NSDictionary *body = [opts objectForKey: @" body" ];
411412 if (body != nil ) {
412413 for (NSString *key in body) {
@@ -426,7 +427,7 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name
426427 }
427428 request.HTTPHeaders = existingHeaders;
428429 }
429-
430+
430431 [request performRequestWithHandler: ^(DCTAuthResponse *response, NSError *error) {
431432 if (error != nil ) {
432433 NSDictionary *errorDict = @{
@@ -503,6 +504,7 @@ - (DCTAuthRequestMethod) getRequestMethodByString:(NSString *) method
503504- (NSDictionary *) getAccountResponse : (DCTAuthAccount *) account
504505 cfg : (NSDictionary *)cfg
505506{
507+ NSArray *ignoredCredentialProperties = @[@" superclass" , @" hash" , @" description" , @" debugDescription" ];
506508 NSString *version = [cfg valueForKey: @" auth_version" ];
507509 NSMutableDictionary *accountResponse = [@{
508510 @" authorized" : @(account.authorized ),
@@ -521,23 +523,51 @@ - (NSDictionary *) getAccountResponse:(DCTAuthAccount *) account
521523 } else if ([version isEqualToString: @" 2.0" ]) {
522524 DCTOAuth2Credential *credential = account.credential ;
523525 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];
531528 [accountResponse setObject: cred forKey: @" credentials" ];
532529 }
533530 }
534531 [accountResponse setValue: [account identifier ] forKey: @" identifier" ];
535532 if (account.userInfo != nil ) {
536- [accountResponse setObject: [account userInfo ] forKey: @" user_info" ];
537- }
533+ [accountResponse setObject: [account userInfo ] forKey: @" user_info" ];
534+ }
538535 return accountResponse;
539536}
540537
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+
541571- (void ) clearPending
542572{
543573 OAuthManager *manager = [OAuthManager sharedManager ];
0 commit comments