Skip to content

Commit afc8f14

Browse files
WEB-1032: fix 2FA email OTP not working in login
The two-factor-authentication component uses ChangeDetectionStrategy.OnPush but never calls markForCheck() after its asynchronous state updates, so the view was never refreshed: - Delivery methods loaded via getDeliveryMethods().subscribe() were never rendered, so the login screen showed "Please select a delivery method:" with no radio options and a permanently-disabled "Request OTP" button. - otpRequested / tokenValidityTime set after requestOTP() never revealed the OTP entry field. - loading / resendOTPLoading spinner states were also not reflected. Inject ChangeDetectorRef and call markForCheck() after each async state mutation (delivery-method load, requestOTP, validateOTP, resendOTP). Verified end-to-end against the 2fa.mifos.community backend and a local Fineract instance: the email delivery method now renders, the Request OTP button enables on selection, and the OTP entry field appears.
1 parent ac714b3 commit afc8f14

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

src/app/login/two-factor-authentication/two-factor-authentication.component.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
/** Angular Imports */
10-
import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core';
10+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, inject } from '@angular/core';
1111
import { FormGroup, FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
1212

1313
/** rxjs Imports */
@@ -44,6 +44,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
4444
export class TwoFactorAuthenticationComponent implements OnInit {
4545
private formBuilder = inject(FormBuilder);
4646
private authenticationService = inject(AuthenticationService);
47+
private changeDetectorRef = inject(ChangeDetectorRef);
4748

4849
/** Available delivery methods to receive OTP. */
4950
twoFactorAuthenticationDeliveryMethods: any;
@@ -71,6 +72,8 @@ export class TwoFactorAuthenticationComponent implements OnInit {
7172
this.createTwoFactorAuthenticationDeliveryMethodForm();
7273
this.authenticationService.getDeliveryMethods().subscribe((deliveryMethods: any) => {
7374
this.twoFactorAuthenticationDeliveryMethods = deliveryMethods;
75+
// OnPush: the delivery methods arrive asynchronously, so notify the view to render the options.
76+
this.changeDetectorRef.markForCheck();
7477
});
7578
}
7679

@@ -92,12 +95,15 @@ export class TwoFactorAuthenticationComponent implements OnInit {
9295
// Angular Material Bug: Validation errors won't get removed on reset.
9396
this.twoFactorAuthenticationDeliveryMethodForm.enable();
9497
this.loading = false;
98+
this.changeDetectorRef.markForCheck();
9599
})
96100
)
97101
.subscribe((response: any) => {
98102
this.createTwoFactorAuthenticationForm();
99103
this.otpRequested = true;
100104
this.tokenValidityTime = response.tokenLiveTimeInSec;
105+
// OnPush: reveal the OTP entry field once the OTP has been requested.
106+
this.changeDetectorRef.markForCheck();
101107
});
102108
}
103109

@@ -116,6 +122,7 @@ export class TwoFactorAuthenticationComponent implements OnInit {
116122
// Angular Material Bug: Validation errors won't get removed on reset.
117123
this.twoFactorAuthenticationForm.enable();
118124
this.loading = false;
125+
this.changeDetectorRef.markForCheck();
119126
})
120127
)
121128
.subscribe();
@@ -136,6 +143,7 @@ export class TwoFactorAuthenticationComponent implements OnInit {
136143
// Angular Material Bug: Validation errors won't get removed on reset.
137144
this.twoFactorAuthenticationForm.enable();
138145
this.resendOTPLoading = false;
146+
this.changeDetectorRef.markForCheck();
139147
})
140148
)
141149
.subscribe();

0 commit comments

Comments
 (0)