@@ -66,7 +66,20 @@ - (BFTask *)logInCurrentUserAsyncWithSessionToken:(NSString *)sessionToken {
6666 message: @" Invalid Session Token." ]];
6767 }
6868
69- PFUser *user = [PFUser _objectFromDictionary: dictionary
69+ // Sanitize response: do not persist transient MFA authData provider
70+ NSMutableDictionary *sanitized = [dictionary mutableCopy ];
71+ id authData = sanitized[@" authData" ];
72+ if ([authData isKindOfClass: [NSDictionary class ]] && authData[@" mfa" ]) {
73+ NSMutableDictionary *mutableAuth = [authData mutableCopy ];
74+ [mutableAuth removeObjectForKey: @" mfa" ]; // transient provider, do not persist
75+ if (mutableAuth.count > 0 ) {
76+ sanitized[@" authData" ] = mutableAuth;
77+ } else {
78+ [sanitized removeObjectForKey: @" authData" ];
79+ }
80+ }
81+
82+ PFUser *user = [PFUser _objectFromDictionary: sanitized
7083 defaultClassName: [PFUser parseClassName ]
7184 completeData: YES ];
7285 // Serialize the object to disk so we can later access it via currentUser
@@ -113,6 +126,46 @@ - (BFTask *)logInCurrentUserAsyncWithUsername:(NSString *)username
113126 }];
114127}
115128
129+ - (BFTask *)logInCurrentUserAsyncWithUsername : (NSString *)username
130+ password : (NSString *)password
131+ parameters : (NSDictionary *)parameters
132+ revocableSession : (BOOL )revocableSession {
133+ @weakify (self);
134+ return [[BFTask taskFromExecutor: [BFExecutor defaultPriorityBackgroundExecutor ] withBlock: ^id {
135+ NSError *error = nil ;
136+ NSMutableDictionary *merged = [@{ @" username" : username ?: @" " ,
137+ @" password" : password ?: @" " } mutableCopy];
138+ if (parameters.count > 0 ) {
139+ // Prevent authData from being persisted later by only sending it with the request body
140+ // and not mutating the PFUser object here. The server response will drive authData merge.
141+ [merged addEntriesFromDictionary: parameters];
142+ }
143+ PFRESTCommand *command = [PFRESTUserCommand logInUserCommandWithParameters: merged
144+ revocableSession: revocableSession
145+ error: &error];
146+ PFPreconditionReturnFailedTask (command, error);
147+ return [self .commonDataSource.commandRunner runCommandAsync: command
148+ withOptions: PFCommandRunningOptionRetryIfFailed];
149+ }] continueWithSuccessBlock: ^id (BFTask *task) {
150+ @strongify (self);
151+ PFCommandResult *result = task.result ;
152+ NSDictionary *dictionary = result.result ;
153+
154+ if ([dictionary isKindOfClass: [NSNull class ]] || !dictionary) {
155+ return [BFTask taskWithError: [PFErrorUtilities errorWithCode: kPFErrorObjectNotFound
156+ message: @" Invalid login credentials." ]];
157+ }
158+
159+ PFUser *user = [PFUser _objectFromDictionary: dictionary
160+ defaultClassName: [PFUser parseClassName ]
161+ completeData: YES ];
162+ PFCurrentUserController *controller = self.coreDataSource .currentUserController ;
163+ return [[controller saveCurrentObjectAsync: user] continueWithBlock: ^id (BFTask *task) {
164+ return user;
165+ }];
166+ }];
167+ }
168+
116169- (BFTask *)logInCurrentUserAsyncWithAuthType : (NSString *)authType
117170 authData : (NSDictionary *)authData
118171 revocableSession : (BOOL )revocableSession {
0 commit comments