4848#import " MSIDAuthenticationScheme.h"
4949#import " MSIDFamilyRefreshToken.h"
5050#import " MSIDAADTokenRequestServerTelemetry.h"
51+ #import " MSIDBartFeatureUtil.h"
52+ #import " MSIDBoundRefreshToken.h"
5153
5254@interface MSIDDefaultTokenCacheAccessor ()
5355{
@@ -132,6 +134,15 @@ - (MSIDRefreshToken *)getRefreshTokenWithAccount:(MSIDAccountIdentifier *)accoun
132134 context : (id <MSIDRequestContext>)context
133135 error : (NSError *__autoreleasing *)error
134136{
137+ MSIDBoundRefreshToken *boundAppRefreshToken = [self getBoundApplicationRefreshTokenWithAccount: accountIdentifier
138+ familyId: familyId
139+ configuration: configuration
140+ context: context
141+ error: error];
142+ if (boundAppRefreshToken)
143+ {
144+ return boundAppRefreshToken;
145+ }
135146 NSError *frtError = nil ;
136147 MSIDIsFRTEnabledStatus frtStatus = [_accountCredentialCache checkFRTEnabled: context error: &frtError];
137148 BOOL frtEnabled = frtStatus == MSIDIsFRTEnabledStatusEnabled;
@@ -151,7 +162,6 @@ - (MSIDRefreshToken *)getRefreshTokenWithAccount:(MSIDAccountIdentifier *)accoun
151162#endif
152163
153164 MSIDCredentialType credentialType = frtEnabled ? MSIDFamilyRefreshTokenType : MSIDRefreshTokenType;
154-
155165 MSIDRefreshToken *refreshToken = [self getRefreshableTokenWithAccount: accountIdentifier
156166 familyId: familyId
157167 credentialType: credentialType
@@ -193,6 +203,44 @@ - (MSIDRefreshToken *)getRefreshTokenWithAccount:(MSIDAccountIdentifier *)accoun
193203 return nil ;
194204}
195205
206+ // / Get a bound refresh token if available. Returns nil if not found or if feature is disabled.
207+ - (MSIDBoundRefreshToken *)getBoundApplicationRefreshTokenWithAccount : (MSIDAccountIdentifier *)accountIdentifier
208+ familyId : (NSString *)familyId
209+ configuration : (MSIDConfiguration *)configuration
210+ context : (id <MSIDRequestContext>)context
211+ error : (NSError *__autoreleasing *)error
212+ {
213+ MSIDBoundRefreshToken *boundAppRefreshToken;
214+ if ([[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ])
215+ {
216+ boundAppRefreshToken = (MSIDBoundRefreshToken *)[self getRefreshableTokenWithAccount: accountIdentifier
217+ familyId: familyId
218+ credentialType: MSIDBoundRefreshTokenType
219+ configuration: configuration
220+ context: context
221+ error: error];
222+ if (boundAppRefreshToken)
223+ {
224+ return boundAppRefreshToken;
225+ }
226+ for (id <MSIDCacheAccessor> accessor in _otherAccessors)
227+ {
228+ boundAppRefreshToken = (MSIDBoundRefreshToken *)[accessor getRefreshTokenWithAccount: accountIdentifier
229+ familyId: familyId
230+ configuration: configuration
231+ context: context
232+ error: error];
233+
234+ if (boundAppRefreshToken)
235+ {
236+ MSID_LOG_WITH_CTX (MSIDLogLevelInfo, context, @" (Default accessor) Found Bound app refresh token in a different accessor %@ " , [accessor class ]);
237+ return boundAppRefreshToken;
238+ }
239+ }
240+ }
241+ return nil ;
242+ }
243+
196244- (MSIDPrimaryRefreshToken *)getPrimaryRefreshTokenWithAccount : (MSIDAccountIdentifier *)accountIdentifier
197245 familyId : (NSString *)familyId
198246 configuration : (MSIDConfiguration *)configuration
@@ -254,7 +302,14 @@ - (MSIDRefreshToken *)getRefreshableTokenWithAccount:(MSIDAccountIdentifier *)ac
254302 context : (id <MSIDRequestContext>)context
255303 error : (NSError *__autoreleasing *)error
256304{
257- if (credentialType != MSIDRefreshTokenType && credentialType != MSIDPrimaryRefreshTokenType && credentialType != MSIDFamilyRefreshTokenType) return nil ;
305+ BOOL shouldQueryBarts = [[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ];
306+ if (credentialType != MSIDRefreshTokenType &&
307+ credentialType != MSIDPrimaryRefreshTokenType &&
308+ credentialType != MSIDFamilyRefreshTokenType &&
309+ (!shouldQueryBarts || credentialType != MSIDBoundRefreshTokenType))
310+ {
311+ return nil ;
312+ }
258313
259314 // For nested auth, get the RT using the broker/hub's client id
260315 NSString *clientId = [configuration isNestedAuthProtocol ] ? configuration.nestedAuthBrokerClientId : configuration.clientId ;
@@ -817,12 +872,20 @@ - (BOOL)validateAndRemoveRefreshToken:(MSIDRefreshToken *)token
817872 MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" Error checking FRT enabled status, not using new FRT." );
818873 }
819874
820- MSIDCredentialType credentialType = frtEnabled ? MSIDFamilyRefreshTokenType : MSIDRefreshTokenType;
875+ BOOL result;
876+ if ([[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ])
877+ {
878+ result = [self validateAndRemoveRefreshableToken: token
879+ credentialType: MSIDBoundRefreshTokenType
880+ context: context
881+ error: error];
882+ }
821883
822- BOOL result = [self validateAndRemoveRefreshableToken: token
823- credentialType: credentialType
824- context: context
825- error: error];
884+ MSIDCredentialType credentialType = frtEnabled ? MSIDFamilyRefreshTokenType : MSIDRefreshTokenType;
885+ result = [self validateAndRemoveRefreshableToken: token
886+ credentialType: credentialType
887+ context: context
888+ error: error];
826889
827890 // If family refresh token is not enabled, return list of regular refresh tokens
828891 if (!frtEnabled)
@@ -851,7 +914,11 @@ - (BOOL)validateAndRemoveRefreshableToken:(MSIDRefreshToken *)token
851914 context : (id <MSIDRequestContext>)context
852915 error : (NSError *__autoreleasing*)error
853916{
854- if (credentialType != MSIDRefreshTokenType && credentialType != MSIDPrimaryRefreshTokenType && credentialType != MSIDFamilyRefreshTokenType)
917+ BOOL shouldBartBeRemoved = [[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ];
918+ if (credentialType != MSIDRefreshTokenType &&
919+ credentialType != MSIDPrimaryRefreshTokenType &&
920+ credentialType != MSIDFamilyRefreshTokenType &&
921+ (!shouldBartBeRemoved || credentialType != MSIDBoundRefreshTokenType))
855922 {
856923 return NO ;
857924 }
@@ -995,6 +1062,20 @@ - (BOOL)saveRefreshTokenWithConfiguration:(MSIDConfiguration *)configuration
9951062
9961063 if (![NSString msidIsStringNilOrBlank: refreshToken.familyId])
9971064 {
1065+ // If FRT is a bound refresh token, we can assume it to be sFRT bound app refresh token
1066+ if ([[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ] &&
1067+ refreshToken.credentialType == MSIDBoundRefreshTokenType)
1068+ {
1069+ MSIDBoundRefreshToken *bart = (MSIDBoundRefreshToken *)refreshToken;
1070+ if (bart && bart.boundDeviceId )
1071+ {
1072+ MSID_LOG_WITH_CTX_PII (MSIDLogLevelVerbose, context, @" (Default accessor) Saving the sFRT as family bound refresh token %@ " , MSID_EUII_ONLY_LOG_MASKABLE (refreshToken));
1073+ return [self saveToken: refreshToken
1074+ context: context
1075+ error: error];
1076+ }
1077+ }
1078+
9981079 NSError *frtError = nil ;
9991080 // Check if FRT is enabled, this will update the configuration object, and then use it to decide if
10001081 // we should save the token as FRT or legacy RT (with familyId, if it contains that value).
@@ -1066,7 +1147,9 @@ - (BOOL)removeToken:(MSIDBaseToken *)token
10661147 CONDITIONAL_START_CACHE_EVENT (event, MSID_TELEMETRY_EVENT_TOKEN_CACHE_DELETE, context);
10671148 BOOL result = [_accountCredentialCache removeCredential: token.tokenCacheItem context: context error: error];
10681149
1069- if (result && (token.credentialType == MSIDRefreshTokenType || token.credentialType == MSIDFamilyRefreshTokenType))
1150+ if (result && (token.credentialType == MSIDRefreshTokenType ||
1151+ token.credentialType == MSIDFamilyRefreshTokenType ||
1152+ ([[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ] && token.credentialType == MSIDBoundRefreshTokenType)))
10701153 {
10711154 [_accountCredentialCache saveWipeInfoWithContext: context error: nil ];
10721155 }
@@ -1131,7 +1214,9 @@ - (MSIDBaseToken *)getTokenWithEnvironment:(NSString *)environment
11311214 return resultTokens[0 ];
11321215 }
11331216
1134- if (cacheQuery.credentialType == MSIDRefreshTokenType || cacheQuery.credentialType == MSIDFamilyRefreshTokenType)
1217+ if (cacheQuery.credentialType == MSIDRefreshTokenType ||
1218+ cacheQuery.credentialType == MSIDFamilyRefreshTokenType ||
1219+ ([[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ] && cacheQuery.credentialType == MSIDBoundRefreshTokenType))
11351220 {
11361221 NSError *wipeError = nil ;
11371222 CONDITIONAL_STOP_FAILED_CACHE_EVENT (event, [_accountCredentialCache wipeInfoWithContext: context error: &wipeError], context);
@@ -1288,7 +1373,6 @@ - (BOOL)saveAccount:(MSIDAccount *)account
12881373 }
12891374
12901375 MSIDCredentialType credentialType = frtEnabled ? MSIDFamilyRefreshTokenType : MSIDRefreshTokenType;
1291-
12921376 NSSet <NSString *> *firstSet = [self homeAccountIdsFromRTsWithAuthority: authority
12931377 clientId: clientId
12941378 familyId: familyId
@@ -1303,6 +1387,28 @@ - (BOOL)saveAccount:(MSIDAccount *)account
13031387 return firstSet;
13041388 }
13051389
1390+ if ([[MSIDBartFeatureUtil sharedInstance ] isBartFeatureEnabled ])
1391+ {
1392+ NSSet <NSString *> *bartSet = [self homeAccountIdsFromRTsWithAuthority: authority
1393+ clientId: clientId
1394+ familyId: familyId
1395+ credentialType: MSIDBoundRefreshTokenType
1396+ accountCredentialCache: accountCredentialCache
1397+ context: context
1398+ error: error];
1399+ if (bartSet)
1400+ {
1401+ [firstSet setByAddingObjectsFromSet: bartSet];
1402+ }
1403+ else
1404+ {
1405+ if (error)
1406+ {
1407+ MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" (Default accessor) Failed to retrieve homeAccountIds from BARTs: %@ " , MSID_PII_LOG_MASKABLE (*error));
1408+ }
1409+ }
1410+ }
1411+
13061412 NSSet <NSString *> *secondSet = [self homeAccountIdsFromRTsWithAuthority: authority
13071413 clientId: clientId
13081414 familyId: familyId
0 commit comments