1818#import " UIImageView+WebCache.h"
1919#import " EaseInputTipsView.h"
2020
21+ #import " Ease_2FA.h"
22+
2123@interface LoginViewController ()
2224@property (nonatomic , strong ) Login *myLogin;
2325
@@ -31,6 +33,9 @@ @interface LoginViewController ()
3133@property (strong , nonatomic ) UIImageView *iconUserView, *bgBlurredView;
3234@property (strong , nonatomic ) EaseInputTipsView *inputTipsView;
3335@property (strong , nonatomic ) UIButton *dismissButton;
36+
37+ @property (assign , nonatomic ) BOOL is2FAUI;
38+ @property (strong , nonatomic ) NSString *otpCode;
3439@end
3540
3641@implementation LoginViewController
@@ -169,7 +174,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
169174
170175- (NSInteger )tableView : (UITableView *)tableView numberOfRowsInSection : (NSInteger )section
171176{
172- return _captchaNeeded? 3 : 2 ;
177+ return _is2FAUI? 1 : _captchaNeeded? 3 : 2 ;
173178}
174179
175180- (UITableViewCell *)tableView : (UITableView *)tableView cellForRowAtIndexPath : (NSIndexPath *)indexPath
@@ -181,36 +186,47 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
181186 }
182187 cell.isForLoginVC = YES ;
183188 __weak typeof (self) weakSelf = self;
184- if (indexPath.row == 0 ) {
189+
190+ if (self.is2FAUI ) {
185191 cell.isCaptcha = NO ;
186- [cell configWithPlaceholder: @" 电子邮箱/个性后缀 " andValue: self .myLogin.email ];
192+ [cell configWithPlaceholder: @" 动态验证码 " andValue: self .otpCode ];
187193 cell.textField .secureTextEntry = NO ;
188194 cell.textValueChangedBlock = ^(NSString *valueStr){
189- weakSelf.inputTipsView .valueStr = valueStr;
190- weakSelf.inputTipsView .active = YES ;
191- weakSelf.myLogin .email = valueStr;
192- [weakSelf.iconUserView setImage: [UIImage imageNamed: @" icon_user_monkey" ]];
193- };
194- cell.editDidEndBlock = ^(NSString *textStr){
195- weakSelf.inputTipsView .active = NO ;
196- [weakSelf refreshIconUserImage ];
197- };
198- }else if (indexPath.row == 1 ){
199- cell.isCaptcha = NO ;
200- [cell configWithPlaceholder: @" 密码" andValue: self .myLogin.password];
201- cell.textField .secureTextEntry = YES ;
202- cell.textValueChangedBlock = ^(NSString *valueStr){
203- weakSelf.myLogin .password = valueStr;
195+ weakSelf.otpCode = valueStr;
204196 };
205197 cell.editDidEndBlock = nil ;
206198 }else {
207- cell.isCaptcha = YES ;
208- [cell configWithPlaceholder: @" 验证码" andValue: self .myLogin.j_captcha];
209- cell.textField .secureTextEntry = NO ;
210- cell.textValueChangedBlock = ^(NSString *valueStr){
211- weakSelf.myLogin .j_captcha = valueStr;
212- };
213- cell.editDidEndBlock = nil ;
199+ if (indexPath.row == 0 ) {
200+ cell.isCaptcha = NO ;
201+ [cell configWithPlaceholder: @" 电子邮箱/个性后缀" andValue: self .myLogin.email];
202+ cell.textField .secureTextEntry = NO ;
203+ cell.textValueChangedBlock = ^(NSString *valueStr){
204+ weakSelf.inputTipsView .valueStr = valueStr;
205+ weakSelf.inputTipsView .active = YES ;
206+ weakSelf.myLogin .email = valueStr;
207+ [weakSelf.iconUserView setImage: [UIImage imageNamed: @" icon_user_monkey" ]];
208+ };
209+ cell.editDidEndBlock = ^(NSString *textStr){
210+ weakSelf.inputTipsView .active = NO ;
211+ [weakSelf refreshIconUserImage ];
212+ };
213+ }else if (indexPath.row == 1 ){
214+ cell.isCaptcha = NO ;
215+ [cell configWithPlaceholder: @" 密码" andValue: self .myLogin.password];
216+ cell.textField .secureTextEntry = YES ;
217+ cell.textValueChangedBlock = ^(NSString *valueStr){
218+ weakSelf.myLogin .password = valueStr;
219+ };
220+ cell.editDidEndBlock = nil ;
221+ }else {
222+ cell.isCaptcha = YES ;
223+ [cell configWithPlaceholder: @" 验证码" andValue: self .myLogin.j_captcha];
224+ cell.textField .secureTextEntry = NO ;
225+ cell.textValueChangedBlock = ^(NSString *valueStr){
226+ weakSelf.myLogin .j_captcha = valueStr;
227+ };
228+ cell.editDidEndBlock = nil ;
229+ }
214230 }
215231 return cell;
216232}
@@ -261,14 +277,31 @@ - (UIView *)customFooterView{
261277 [footerV addSubview: _loginBtn];
262278
263279
264- RAC (self, loginBtn.enabled ) = [RACSignal combineLatest: @[RACObserve (self , myLogin.email), RACObserve (self , myLogin.password), RACObserve (self , myLogin.j_captcha), RACObserve (self , captchaNeeded)] reduce: ^id (NSString *email, NSString *password, NSString *j_captcha, NSNumber *captchaNeeded){
265- if ((captchaNeeded && captchaNeeded.boolValue ) && (!j_captcha || j_captcha.length <= 0 )) {
266- return @(NO );
267- }else {
268- return @((email && email.length > 0 ) && (password && password.length > 0 ));
269- }
270- }];
271-
280+ RAC (self, loginBtn.enabled ) = [RACSignal combineLatest: @[
281+ RACObserve (self , myLogin.email),
282+ RACObserve (self , myLogin.password),
283+ RACObserve (self , myLogin.j_captcha),
284+ RACObserve (self , captchaNeeded),
285+ RACObserve (self , is2FAUI),
286+ RACObserve (self , otpCode)
287+ ]
288+ reduce: ^id (
289+ NSString *email,
290+ NSString *password,
291+ NSString *j_captcha,
292+ NSNumber *captchaNeeded,
293+ NSNumber *is2FAUI,
294+ NSString *otpCode){
295+ if (is2FAUI && is2FAUI.boolValue ) {
296+ return @(otpCode.length > 0 );
297+ }else {
298+ if ((captchaNeeded && captchaNeeded.boolValue ) && (!j_captcha || j_captcha.length <= 0 )) {
299+ return @(NO );
300+ }else {
301+ return @((email && email.length > 0 ) && (password && password.length > 0 ));
302+ }
303+ }
304+ }];
272305 return footerV;
273306}
274307
@@ -320,13 +353,13 @@ - (void)configBottomView{
320353
321354#pragma mark Btn Clicked
322355- (void )sendLogin {
323- NSString *tipMsg = [_myLogin goToLoginTipWithCaptcha: _captchaNeeded];
356+ NSString *tipMsg = self. is2FAUI ? [ self goToLoginTipWith2FA ]: [_myLogin goToLoginTipWithCaptcha: _captchaNeeded];
324357 if (tipMsg) {
325358 kTipAlert (@" %@ " , tipMsg);
326359 return ;
327360 }
328- [self .view endEditing: YES ];
329361
362+ [self .view endEditing: YES ];
330363 if (!_activityIndicator) {
331364 _activityIndicator = [[UIActivityIndicatorView alloc ]
332365 initWithActivityIndicatorStyle:
@@ -339,18 +372,40 @@ - (void)sendLogin{
339372 [_activityIndicator startAnimating ];
340373
341374 __weak typeof (self) weakSelf = self;
342-
343375 _loginBtn.enabled = NO ;
344- [[Coding_NetAPIManager sharedManager ] request_Login_WithParams: [self .myLogin toParams ] andBlock: ^(id data, NSError *error) {
345- weakSelf.loginBtn .enabled = YES ;
346- [weakSelf.activityIndicator stopAnimating ];
347- if (data) {
348- [Login setPreUserEmail: self .myLogin.email];// 记住登录账号
349- [((AppDelegate *)[UIApplication sharedApplication ].delegate) setupTabViewController ];
350- }else {
351- [weakSelf refreshCaptchaNeeded ];
352- }
353- }];
376+
377+ if (self.is2FAUI ) {
378+ [[Coding_NetAPIManager sharedManager ] request_Login_With2FA: self .otpCode andBlock: ^(id data, NSError *error) {
379+ weakSelf.loginBtn .enabled = YES ;
380+ [weakSelf.activityIndicator stopAnimating ];
381+ if (data) {
382+ [Login setPreUserEmail: self .myLogin.email];// 记住登录账号
383+ [((AppDelegate *)[UIApplication sharedApplication ].delegate) setupTabViewController ];
384+ }else {
385+ NSString *status_expired = error.userInfo [@" msg" ][@" user_login_status_expired" ];
386+ if (status_expired.length > 0 ) {
387+ [weakSelf changeUITo2FAWithGK: nil ];
388+ }
389+ }
390+ }];
391+ }else {
392+ [[Coding_NetAPIManager sharedManager ] request_Login_WithParams: [self .myLogin toParams ] andBlock: ^(id data, NSError *error) {
393+ weakSelf.loginBtn .enabled = YES ;
394+ [weakSelf.activityIndicator stopAnimating ];
395+ if (data) {
396+ [Login setPreUserEmail: self .myLogin.email];// 记住登录账号
397+ [((AppDelegate *)[UIApplication sharedApplication ].delegate) setupTabViewController ];
398+ }else {
399+ NSString *global_key = error.userInfo [@" msg" ][@" two_factor_auth_code_not_empty" ];
400+ if (global_key.length > 0 ) {
401+ [weakSelf changeUITo2FAWithGK: global_key];
402+ }else {
403+ [self showError: error];
404+ [weakSelf refreshCaptchaNeeded ];
405+ }
406+ }
407+ }];
408+ }
354409}
355410
356411- (IBAction )cannotLoginBtnClicked : (id )sender {
@@ -374,12 +429,37 @@ - (IBAction)goRegisterVC:(id)sender {
374429}
375430
376431- (void )dismissButtonClicked {
377- [self dismissViewControllerAnimated: YES completion: nil ];
432+ if (self.is2FAUI ) {
433+ self.is2FAUI = NO ;
434+ }else {
435+ [self dismissViewControllerAnimated: YES completion: nil ];
436+ }
378437}
379438
380- - (void )dealloc
381- {
382- _myTableView.delegate = nil ;
383- _myTableView.dataSource = nil ;
439+ #pragma mark 2FA
440+ - (void )changeUITo2FAWithGK : (NSString *)global_key {
441+ self.otpCode = [OTPListViewController otpCodeWithGK: global_key];
442+ self.is2FAUI = global_key.length > 0 ;
443+ if (self.otpCode ) {
444+ [self sendLogin ];
445+ }
446+ }
447+
448+ - (void )setIs2FAUI : (BOOL )is2FAUI {
449+ _is2FAUI = is2FAUI;
450+ if (!_is2FAUI) {
451+ self.otpCode = nil ;
452+ }
453+ [self .myTableView reloadSections: [NSIndexSet indexSetWithIndex: 0 ] withRowAnimation: _is2FAUI? UITableViewRowAnimationLeft: UITableViewRowAnimationRight];
454+ }
455+
456+ - (NSString *)goToLoginTipWith2FA {
457+ NSString *tipStr = nil ;
458+ if (self.otpCode .length <= 0 ) {
459+ tipStr = @" 动态验证码不能为空" ;
460+ }else if (![self .otpCode isPureInt ] || self.otpCode .length != 6 ){
461+ tipStr = @" 动态验证码必须是一个6位数字" ;
462+ }
463+ return tipStr;
384464}
385465@end
0 commit comments