Skip to content

Commit b4cd581

Browse files
committed
fix(authentication): handle and show login error state
1 parent 7926041 commit b4cd581

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

lib/features/authentication/bloc/authentication_bloc.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState>
4242
emit(state.copyWith(status: AuthenticationStatus.loggingIn));
4343
await _authenticationRepository.loginWithPassword(userCredential).match((e) {
4444
handle(e);
45-
emit(state.copyWith(status: AuthenticationStatus.failure));
45+
emit(state.copyWith(status: AuthenticationStatus.failure, loginException: e));
4646
}, (_) => emit(state.copyWith(status: AuthenticationStatus.success))).run();
4747
}
4848
}

lib/features/authentication/repository/authentication_repository.dart

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,46 @@ class AuthenticationRepository with LoggerMixin {
129129
if (resp.statusCode != HttpStatus.ok) {
130130
return left(HttpRequestFailedException(resp.statusCode));
131131
}
132-
final loginResult = LoginResultMapper.fromJson(resp.data as String);
133-
if (loginResult.status != 0) {
134-
error('failed to login: $loginResult}');
135-
return left(LoginOtherErrorException('login failed'));
136-
}
137132

138-
// Here we get complete user info.
139-
final userInfo = UserLoginInfo(username: loginResult.values!.username, uid: int.parse(loginResult.values!.uid!));
140-
// First combine user info and cookie together.
141-
await cookie.updateUserInfo(userInfo);
142-
// Second, save credential in storage.
143-
await cookie.saveCookieToStorage();
144-
// Refresh the cookie in global cookie provider.
145-
await getIt.get<CookieProvider>().loadCookieFromStorage(userInfo);
146-
// Finally save authed user info and update authentication status to
147-
// let auth stream subscribers update their status.
148-
await _markAuthenticated(userInfo);
149-
debug('end login with success');
133+
return Option.tryCatch(() =>
134+
LoginResultMapper.fromJson(resp.data as String)
135+
).match(() {
136+
// Can not convert to regular login success result.
137+
final json = jsonDecode(resp.data as String) as Map<String, dynamic>?;
138+
final message = json?['message'] as String?;
139+
140+
if (message == null) {
141+
return left(LoginOtherErrorException('message not found'));
142+
}
143+
144+
final err = switch (message) {
145+
'login_invalid' => LoginInvalidCredentialException(),
146+
'login_strike' => LoginAttemptLimitException(),
147+
'err_login_captcha_invalid' => LoginIncorrectCaptchaException(),
148+
final String v => LoginOtherErrorException('unknown error message $v'),
149+
};
150+
return left(err);
151+
}, (loginResult) async {
152+
if (loginResult.status != 0) {
153+
error('failed to login: $loginResult}');
154+
return left(LoginOtherErrorException('login failed, status=${loginResult.status}'));
155+
}
156+
157+
// Here we get complete user info.
158+
final userInfo = UserLoginInfo(username: loginResult.values!.username, uid: int.parse(loginResult.values!.uid!));
159+
// First combine user info and cookie together.
160+
await cookie.updateUserInfo(userInfo);
161+
// Second, save credential in storage.
162+
await cookie.saveCookieToStorage();
163+
// Refresh the cookie in global cookie provider.
164+
await getIt.get<CookieProvider>().loadCookieFromStorage(userInfo);
165+
// Finally save authed user info and update authentication status to
166+
// let auth stream subscribers update their status.
167+
await _markAuthenticated(userInfo);
168+
debug('end login with success');
150169

151-
return rightVoid();
170+
return rightVoid();
171+
});
152172
});
153173

154174
/// Parse logged user info from html [document].

0 commit comments

Comments
 (0)