@@ -66,7 +66,20 @@ - (BFTask *)logInCurrentUserAsyncWithSessionToken:(NSString *)sessionToken {
66
66
message: @" Invalid Session Token." ]];
67
67
}
68
68
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
70
83
defaultClassName: [PFUser parseClassName ]
71
84
completeData: YES ];
72
85
// Serialize the object to disk so we can later access it via currentUser
@@ -113,6 +126,46 @@ - (BFTask *)logInCurrentUserAsyncWithUsername:(NSString *)username
113
126
}];
114
127
}
115
128
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
+
116
169
- (BFTask *)logInCurrentUserAsyncWithAuthType : (NSString *)authType
117
170
authData : (NSDictionary *)authData
118
171
revocableSession : (BOOL )revocableSession {
0 commit comments