feat: Implement support chat functionality, add 2FA verification screen and routing, and update dependencies.

This commit is contained in:
pradeepkumar
2026-03-11 13:26:16 +05:30
parent 4780eb9a63
commit 6928697c5c
17 changed files with 1660 additions and 20 deletions

View File

@@ -16,6 +16,9 @@ class AuthState {
final String? errorMessage;
final List<FieldError> fieldErrors;
final String registeredEmail;
final bool requiresTwoFactor;
final String? tempToken;
final String? twoFactorEmail;
const AuthState({
this.status = AuthStatus.initial,
@@ -23,6 +26,9 @@ class AuthState {
this.errorMessage,
this.fieldErrors = const [],
this.registeredEmail = '',
this.requiresTwoFactor = false,
this.tempToken,
this.twoFactorEmail,
});
AuthState copyWith({
@@ -31,6 +37,9 @@ class AuthState {
String? errorMessage,
List<FieldError>? fieldErrors,
String? registeredEmail,
bool? requiresTwoFactor,
String? tempToken,
String? twoFactorEmail,
}) {
return AuthState(
status: status ?? this.status,
@@ -38,6 +47,9 @@ class AuthState {
errorMessage: errorMessage,
fieldErrors: fieldErrors ?? this.fieldErrors,
registeredEmail: registeredEmail ?? this.registeredEmail,
requiresTwoFactor: requiresTwoFactor ?? this.requiresTwoFactor,
tempToken: tempToken ?? this.tempToken,
twoFactorEmail: twoFactorEmail ?? this.twoFactorEmail,
);
}
@@ -112,8 +124,10 @@ class AuthNotifier extends StateNotifier<AuthState> {
if (result['requiresTwoFactor'] == true) {
state = state.copyWith(
status: AuthStatus.error,
errorMessage: '2FA verification required',
status: AuthStatus.initial,
requiresTwoFactor: true,
tempToken: result['tempToken'] as String?,
twoFactorEmail: email,
);
return;
}
@@ -189,6 +203,74 @@ class AuthNotifier extends StateNotifier<AuthState> {
}
}
Future<void> verifyTwoFactor(String token) async {
final tempToken = state.tempToken;
if (tempToken == null) return;
state = state.copyWith(
status: AuthStatus.loading,
errorMessage: null,
);
try {
final authResponse = await _repository.verifyTwoFactor(
tempToken: tempToken,
token: token,
);
state = AuthState(
status: AuthStatus.authenticated,
user: authResponse.user,
);
_initPushNotifications();
} on ApiException catch (e) {
state = state.copyWith(
status: AuthStatus.initial,
errorMessage: e.message,
);
} catch (e) {
state = state.copyWith(
status: AuthStatus.initial,
errorMessage: 'Verification failed. Please try again.',
);
}
}
Future<void> verifyBackupCode(String backupCode) async {
final tempToken = state.tempToken;
if (tempToken == null) return;
state = state.copyWith(
status: AuthStatus.loading,
errorMessage: null,
);
try {
final authResponse = await _repository.verifyBackupCode(
tempToken: tempToken,
backupCode: backupCode,
);
state = AuthState(
status: AuthStatus.authenticated,
user: authResponse.user,
);
_initPushNotifications();
} on ApiException catch (e) {
state = state.copyWith(
status: AuthStatus.initial,
errorMessage: e.message,
);
} catch (e) {
state = state.copyWith(
status: AuthStatus.initial,
errorMessage: 'Verification failed. Please try again.',
);
}
}
void clearTwoFactor() {
state = const AuthState();
}
void _initPushNotifications() {
final push = PushNotificationService();
push.initialize().then((_) => push.registerAfterLogin());