2929#import " SFManagedPreferences.h"
3030#import " SFApplicationHelper.h"
3131#import " SFSDKAppFeatureMarkers.h"
32- #import " SFSDKDevInfoViewController.h"
3332#import " SFDefaultUserManagementViewController.h"
33+ #import " SFSDKAuthRootController.h"
3434#import < SalesforceSDKCommon/SFSwiftDetectUtil.h>
3535#import " SFSDKEncryptedURLCache.h"
3636#import " SFSDKNullURLCache.h"
@@ -471,25 +471,66 @@ - (NSString *)devInfoTitleString
471471
472472- (NSArray <SFSDKDevAction *>*) getDevActions : (UIViewController *)presentedViewController
473473{
474- return @[
475- [[SFSDKDevAction alloc ]initWith:@" Show dev info" handler: ^{
476- SFSDKDevInfoViewController *devInfo = [[SFSDKDevInfoViewController alloc ] init ];
477- [presentedViewController presentViewController: devInfo animated: NO completion: nil ];
478- }],
479- [[SFSDKDevAction alloc ]initWith:@" Logout" handler: ^{
480- [[SFUserAccountManager sharedInstance ] logout: SFLogoutReasonUserInitiated];
481- }],
482- [[SFSDKDevAction alloc ]initWith:@" Switch user" handler: ^{
483- SFDefaultUserManagementViewController *umvc = [[SFDefaultUserManagementViewController alloc ] initWithCompletionBlock: ^(SFUserManagementAction action) {
484- [presentedViewController dismissViewControllerAnimated: YES completion: nil ];
485- }];
486- [presentedViewController presentViewController: umvc animated: YES completion: nil ];
487- }],
488- [[SFSDKDevAction alloc ]initWith:@" Inspect Key-Value Store" handler: ^{
489- UIViewController *keyValueStoreInspector = [[SFSDKKeyValueEncryptedFileStoreViewController new ] createUI ];
490- [presentedViewController presentViewController: keyValueStoreInspector animated: YES completion: nil ];
491- }]
492- ];
474+ NSMutableArray <SFSDKDevAction *> *actions = [NSMutableArray array ];
475+ SFUserAccountManager *userAccountManager = [SFUserAccountManager sharedInstance ];
476+ SFUserAccount *currentUser = userAccountManager.currentUser ;
477+
478+ // Check if we're showing the login screen
479+ BOOL isShowingLogin = [presentedViewController isKindOfClass: [SFLoginViewController class ]];
480+ // TODO uncomment to support advanced auth case (once we add code to restart auth in that case below)
481+ // || [presentedViewController.presentingViewController isKindOfClass:[SFSDKAuthRootController class]];
482+
483+ // Show dev info - always available
484+ [actions addObject: [[SFSDKDevAction alloc ]initWith:@" Show dev info" handler: ^{
485+ UIViewController *devInfo = [SFSDKDevInfoViewController makeViewController ];
486+ [presentedViewController presentViewController: devInfo animated: YES completion: nil ];
487+ }]];
488+
489+ // Login Options - only show on login screen
490+ if (isShowingLogin) {
491+ [actions addObject: [[SFSDKDevAction alloc ]initWith:@" Login Options" handler: ^{
492+ UIViewController *configPicker = [BootConfigPickerViewController makeViewControllerOnConfigurationCompleted: ^{
493+ [presentedViewController dismissViewControllerAnimated: YES completion: ^{
494+ // Restart authentication with the updated configuration
495+ if ([presentedViewController isKindOfClass: [SFLoginViewController class ]]) {
496+ [[SFUserAccountManager sharedInstance ] restartAuthenticationForViewController: (SFLoginViewController *)presentedViewController];
497+ }
498+ // TODO support advanced auth case
499+ }];
500+ }];
501+ [presentedViewController presentViewController: configPicker animated: YES completion: nil ];
502+ }]];
503+ }
504+
505+ // Logout - only show if there's a current user and not on login screen
506+ if (currentUser && !isShowingLogin) {
507+ [actions addObject: [[SFSDKDevAction alloc ]initWith:@" Logout" handler: ^{
508+ [[SFUserAccountManager sharedInstance ] logout: SFLogoutReasonUserInitiated];
509+ }]];
510+ }
511+
512+ // Switch user - only show if there's a current user and not on login screen
513+ if (currentUser && !isShowingLogin) {
514+ [actions addObject: [[SFSDKDevAction alloc ]initWith:@" Switch user" handler: ^{
515+ SFDefaultUserManagementViewController *umvc = [[SFDefaultUserManagementViewController alloc ] initWithCompletionBlock: ^(SFUserManagementAction action) {
516+ [presentedViewController dismissViewControllerAnimated: YES completion: nil ];
517+ }];
518+ [presentedViewController presentViewController: umvc animated: YES completion: nil ];
519+ }]];
520+ }
521+
522+ // Inspect Key-Value Store - only show if there are stores
523+ BOOL hasGlobalStores = [SFSDKKeyValueEncryptedFileStore allGlobalStoreNames ].count > 0 ;
524+ BOOL hasUserStores = currentUser && [SFSDKKeyValueEncryptedFileStore allStoreNames ].count > 0 ;
525+
526+ if (hasGlobalStores || hasUserStores) {
527+ [actions addObject: [[SFSDKDevAction alloc ]initWith:@" Inspect Key-Value Store" handler: ^{
528+ UIViewController *keyValueStoreInspector = [[SFSDKKeyValueEncryptedFileStoreViewController new ] createUI ];
529+ [presentedViewController presentViewController: keyValueStoreInspector animated: YES completion: nil ];
530+ }]];
531+ }
532+
533+ return [actions copy ];
493534}
494535
495536- (NSArray <NSString *>*) getDevSupportInfos
@@ -498,25 +539,62 @@ - (NSString *)devInfoTitleString
498539 NSMutableArray * devInfos = [NSMutableArray arrayWithArray: @[
499540 @" SDK Version" , SALESFORCE_SDK_VERSION,
500541 @" App Type" , [self getAppTypeAsString ],
501- @" User Agent" , self .userAgentString (@" " ),
542+ @" User Agent" , self .userAgentString (@" " )
543+ ]];
544+ NSArray * allUsers = userAccountManager.allUserAccounts ;
545+ if ([allUsers count ] > 0 ) {
546+ [devInfos addObjectsFromArray: @[
547+ @" Authenticated Users" , [self usersToString: allUsers]
548+ ]];
549+ }
550+
551+ // Auth configuration
552+ [devInfos addObject: @" section:Auth Config" ];
553+ [devInfos addObjectsFromArray: @[
502554 @" Use Web Server Authentication" , [self useWebServerAuthentication ] ? @" YES" : @" NO" ,
555+ @" Use Hybrid Authentication" , [self useHybridAuthentication ] ? @" YES" : @" NO" ,
556+ @" Supports Welcome Discovery" , [self supportsWelcomeDiscovery ] ? @" YES" : @" NO" ,
503557 @" Browser Login Enabled" , [SFUserAccountManager sharedInstance ].useBrowserAuth? @" YES" : @" NO" ,
504558 @" IDP Enabled" , [self idpEnabled ] ? @" YES" : @" NO" ,
505- @" Identity Provider" , [self isIdentityProvider ] ? @" YES" : @" NO" ,
506- @" Current User" , [self userToString: userAccountManager.currentUser],
507- @" Scopes" , [userAccountManager.currentUser.credentials.scopes componentsJoinedByString: @" " ],
508- @" Access Token Expiration" , [self accessTokenExpiration ],
509- @" Authenticated Users" , [self usersToString: userAccountManager.allUserAccounts],
510- @" User Key-Value Stores" , [self safeJoin: [SFSDKKeyValueEncryptedFileStore allStoreNames ] separator: @" , " ],
511- @" Global Key-Value Stores" , [self safeJoin: [SFSDKKeyValueEncryptedFileStore allGlobalStoreNames ] separator: @" , " ]
559+ @" Identity Provider" , [self isIdentityProvider ] ? @" YES" : @" NO"
512560 ]];
513561
514- [devInfos addObjectsFromArray: [self dictToDevInfos: self .appConfig.configDict keyPrefix: @" BootConfig" ]];
562+ // Static bootconfig
563+ [devInfos addObject: @" section:Bootconfig" ];
564+ [devInfos addObjectsFromArray: [self dictToDevInfos: self .appConfig.configDict]];
565+
566+ // Current user info
567+ SFUserAccount* currentUser = userAccountManager.currentUser ;
568+ if (currentUser) {
569+ SFOAuthCredentials* creds = currentUser.credentials ;
570+ [devInfos addObject: @" section:Current User" ];
571+ [devInfos addObjectsFromArray: @[
572+ @" Username" , [self userToString: currentUser],
573+ @" Consumer Key" , creds.clientId ?: @" (nil)" ,
574+ @" Redirect URI" , creds.redirectUri ?: @" (nil)" ,
575+ @" Scopes" , [self scopesToString: currentUser],
576+ @" Instance URL" , [creds.instanceUrl absoluteString ] ?: @" (nil)" ,
577+ @" Token format" , [creds.tokenFormat isEqualToString: @" jwt" ] ? @" jwt" : @" opaque" ,
578+ @" Access Token Expiration" , [self accessTokenExpiration ],
579+ @" Beacon Child Consumer Key" , creds.beaconChildConsumerKey ?: @" (empty)"
580+ ]];
581+ }
515582
583+ // Key Value Stores
584+ NSArray <NSString *>* globalKeyValueStores = [SFSDKKeyValueEncryptedFileStore allGlobalStoreNames ];
585+ NSArray <NSString *>* userKeyValueStores = [SFSDKKeyValueEncryptedFileStore allStoreNames ];
586+ if ([userKeyValueStores count ] > 0 || [globalKeyValueStores count ] > 0 ) {
587+ [devInfos addObject: @" section:Key Value Stores" ];
588+ [devInfos addObjectsFromArray: @[@" Global stores" , [self safeJoin: globalKeyValueStores separator: @" , " ]]];
589+ [devInfos addObjectsFromArray: @[@" User stores" , [self safeJoin: globalKeyValueStores separator: @" , " ]]];
590+ }
591+
592+ // Managed prefs
516593 SFManagedPreferences *managedPreferences = [SFManagedPreferences sharedPreferences ];
517- [devInfos addObjectsFromArray: @[@" Managed" , [managedPreferences hasManagedPreferences ] ? @" YES" : @" NO" ]];
518594 if ([managedPreferences hasManagedPreferences ]) {
519- [devInfos addObjectsFromArray: [self dictToDevInfos: managedPreferences.rawPreferences keyPrefix: @" Managed Pref" ]];
595+ [devInfos addObject: @" section:Managed Pref" ];
596+ [devInfos addObjectsFromArray: @[@" Managed" , [managedPreferences hasManagedPreferences ] ? @" YES" : @" NO" ]];
597+ [devInfos addObjectsFromArray: [self dictToDevInfos: managedPreferences.rawPreferences]];
520598 }
521599
522600 return devInfos;
@@ -542,21 +620,31 @@ - (NSString *) accessTokenExpiration {
542620}
543621
544622- (NSString *) userToString : (SFUserAccount*)user {
545- return user ? user.idData .username : @" " ;
623+ return user.idData .username != nil ? user.idData .username : @" " ;
624+ }
625+
626+ - (NSString *) scopesToString : (SFUserAccount*)user {
627+ return user.credentials .scopes != nil ? [user.credentials.scopes componentsJoinedByString: @" " ] : @" " ;
546628}
547629
548630- (NSString *) usersToString : (NSArray <SFUserAccount*>*)userAccounts {
631+ if (userAccounts == nil ) {
632+ return @" " ;
633+ }
549634 NSMutableArray * usernames = [NSMutableArray new ];
550635 for (SFUserAccount *userAccount in userAccounts) {
551636 [usernames addObject: [self userToString: userAccount]];
552637 }
553638 return [usernames componentsJoinedByString: @" , " ];
554639}
555640
556- - (NSArray *) dictToDevInfos : (NSDictionary *)dict keyPrefix : (NSString *)keyPrefix {
641+ - (NSArray *) dictToDevInfos : (NSDictionary *)dict {
642+ if (dict == nil ) {
643+ return @[];
644+ }
557645 NSMutableArray * devInfos = [NSMutableArray new ];
558646 [dict enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
559- [devInfos addObject: [ NSString stringWithFormat: @" %@ - %@ " , keyPrefix, key] ];
647+ [devInfos addObject: key];
560648 [devInfos addObject: [[NSString stringWithFormat: @" %@ " , obj] stringByReplacingOccurrencesOfString: @" \n " withString: @" " ]];
561649 }];
562650 return devInfos;
0 commit comments