Handle Auth redirect in MailboxDashboardController

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-07-02 15:55:15 +07:00
committed by Dat H. Pham
parent 9a2f0aa356
commit 0873a2b54e
4 changed files with 122 additions and 33 deletions
@@ -78,6 +78,12 @@ import 'package:tmail_ui_user/features/home/domain/usecases/store_session_intera
import 'package:tmail_ui_user/features/identity_creator/domain/state/get_identity_cache_on_web_state.dart'; import 'package:tmail_ui_user/features/identity_creator/domain/state/get_identity_cache_on_web_state.dart';
import 'package:tmail_ui_user/features/identity_creator/domain/usecase/get_identity_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/identity_creator/domain/usecase/get_identity_cache_on_web_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/logout_exception.dart'; import 'package:tmail_ui_user/features/login/domain/exceptions/logout_exception.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_authentication_info_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_stored_oidc_configuration_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_token_oidc_state.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/get_authentication_info_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/get_stored_oidc_configuration_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/get_token_oidc_interactor.dart';
import 'package:tmail_ui_user/features/login/presentation/model/login_navigate_arguments.dart'; import 'package:tmail_ui_user/features/login/presentation/model/login_navigate_arguments.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.dart'; import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
@@ -114,6 +120,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/set_error_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/set_error_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_current_emails_flags_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_current_emails_flags_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_own_email_address_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_own_email_address_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/web_auth_redirect_processor_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/draggable_app_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/draggable_app_state.dart';
@@ -196,6 +203,11 @@ class MailboxDashBoardController extends ReloadableController
final SpamReportController spamReportController = Get.find<SpamReportController>(); final SpamReportController spamReportController = Get.find<SpamReportController>();
final NetworkConnectionController networkConnectionController = Get.find<NetworkConnectionController>(); final NetworkConnectionController networkConnectionController = Get.find<NetworkConnectionController>();
final ComposerManager composerManager = Get.find<ComposerManager>(); final ComposerManager composerManager = Get.find<ComposerManager>();
final getAuthenticationInfoInteractor =
Get.find<GetAuthenticationInfoInteractor>();
final getStoredOidcConfigurationInteractor =
Get.find<GetStoredOidcConfigurationInteractor>();
final getTokenOIDCInteractor = Get.find<GetTokenOIDCInteractor>();
final MoveToMailboxInteractor _moveToMailboxInteractor; final MoveToMailboxInteractor _moveToMailboxInteractor;
final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor; final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor;
@@ -370,7 +382,6 @@ class MailboxDashBoardController extends ReloadableController
@override @override
void handleSuccessViewState(Success success) { void handleSuccessViewState(Success success) {
super.handleSuccessViewState(success);
if (success is SendEmailLoading) { if (success is SendEmailLoading) {
if (currentOverlayContext != null && currentContext != null) { if (currentOverlayContext != null && currentContext != null) {
appToast.showToastMessage( appToast.showToastMessage(
@@ -459,12 +470,23 @@ class MailboxDashBoardController extends ReloadableController
clearMailboxSuccess(success); clearMailboxSuccess(success);
} else if (success is CreateNewRuleFilterSuccess) { } else if (success is CreateNewRuleFilterSuccess) {
handleCreateNewRuleFilterSuccess(success); handleCreateNewRuleFilterSuccess(success);
} else if (success is GetAuthenticationInfoSuccess) {
getStoredOidcConfiguration();
} else if (success is GetStoredOidcConfigurationSuccess) {
getTokenOIDCAction(success.oidcConfiguration);
} else if (success is GetTokenOIDCSuccess) {
synchronizeTokenAndGetSession(
baseUri: success.baseUri,
tokenOIDC: success.tokenOIDC,
oidcConfiguration: success.configuration,
);
} else {
super.handleSuccessViewState(success);
} }
} }
@override @override
void handleFailureViewState(Failure failure) { void handleFailureViewState(Failure failure) {
super.handleFailureViewState(failure);
if (failure is SendEmailFailure) { if (failure is SendEmailFailure) {
_handleSendEmailFailure(failure); _handleSendEmailFailure(failure);
} else if (failure is SaveEmailAsDraftsFailure) { } else if (failure is SaveEmailAsDraftsFailure) {
@@ -499,6 +521,12 @@ class MailboxDashBoardController extends ReloadableController
clearMailboxFailure(failure); clearMailboxFailure(failure);
} else if (failure is CreateNewRuleFilterFailure) { } else if (failure is CreateNewRuleFilterFailure) {
handleCreateNewRuleFilterFailure(failure); handleCreateNewRuleFilterFailure(failure);
} else if (failure is GetAuthenticationInfoFailure) {
tryGetAuthenticatedAccountToUseApp();
} else if (isGetTokenOIDCFailure(failure)) {
backToHomeScreen();
} else {
super.handleFailureViewState(failure);
} }
} }
@@ -711,6 +739,9 @@ class MailboxDashBoardController extends ReloadableController
_handleSessionFromArguments(arguments); _handleSessionFromArguments(arguments);
} else if (arguments is MailtoArguments) { } else if (arguments is MailtoArguments) {
_handleMailtoURL(arguments); _handleMailtoURL(arguments);
} else if (PlatformInfo.isWeb) {
dispatchRoute(DashboardRoutes.thread);
getAuthenticationInfoRedirect();
} else { } else {
dispatchRoute(DashboardRoutes.thread); dispatchRoute(DashboardRoutes.thread);
reload(); reload();
@@ -0,0 +1,45 @@
import 'package:core/presentation/state/failure.dart';
import 'package:dartz/dartz.dart';
import 'package:model/oidc/oidc_configuration.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_stored_oidc_configuration_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_token_oidc_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
extension WebAuthRedirectProcessorExtension on MailboxDashBoardController {
void getAuthenticationInfoRedirect() {
consumeState(getAuthenticationInfoInteractor.execute());
}
void getStoredOidcConfiguration() {
consumeState(getStoredOidcConfigurationInteractor.execute());
}
void getTokenOIDCAction(OIDCConfiguration oidcConfig) {
final baseUri = Uri.tryParse(AppConfig.baseUrl);
if (baseUri == null) {
consumeState(
Stream.value(Left(GetTokenOIDCFailure(CanNotFoundBaseUrl()))),
);
} else {
consumeState(getTokenOIDCInteractor.execute(baseUri, oidcConfig));
}
}
bool isGetTokenOIDCFailure(Failure? failure) {
return failure is GetStoredOidcConfigurationFailure ||
failure is GetTokenOIDCFailure;
}
void tryGetAuthenticatedAccountToUseApp() {
getAuthenticatedAccountAction();
}
void backToHomeScreen() {
pushAndPopAll(AppRoutes.home);
}
}
+30 -23
View File
@@ -1,31 +1,38 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<script> <script>
const AUTH_DESTINATION_KEY = "auth_destination_url"; const AUTH_DESTINATION_KEY = "auth_destination_url";
const AUTH_RESPONSE_KEY = "auth_info"; const AUTH_RESPONSE_KEY = "auth_info";
window.onload = function () { window.onload = function () {
if (window.opener && window.opener !== window) { //Used when working as a popup. Uses post message to respond to the parent window try {
var parent = window.opener ?? window.parent; // Get the original page destination
parent.postMessage(location.href, "*"); const destination = sessionStorage.getItem(AUTH_DESTINATION_KEY) || "/";
} else { //Used for redirect loop functionality. sessionStorage.removeItem(AUTH_DESTINATION_KEY);
//Get the original page destination
const destination = sessionStorage.getItem(AUTH_DESTINATION_KEY || "/");
sessionStorage.removeItem(AUTH_DESTINATION_KEY);
//Store the current window location that will be used to get the information for authentication
sessionStorage.setItem(AUTH_RESPONSE_KEY, window.location);
//Redirect to where we're going so that we can restore state completely // Store the current window location that will be used to get the information for authentication
location.assign(destination); sessionStorage.setItem(AUTH_RESPONSE_KEY, window.location);
}
// Build the redirect URL
let redirectUrl;
if (destination.includes("/login")) {
redirectUrl = destination.replace("/login", "/dashboard?type=normal");
} else {
const separator = destination.endsWith("/") ? "" : "/";
redirectUrl = destination + separator + "dashboard?type=normal";
} }
</script>
// Perform redirection
location.assign(redirectUrl);
} catch (error) {
console.error("[Auth Redirect] Redirection failed:", error);
location.assign("/");
}
};
</script>
<title>Twake Mail</title>
</head> </head>
<body> <body></body>
</body>
</html> </html>
+12 -6
View File
@@ -1,11 +1,12 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<script> <script>
const AUTH_RESPONSE_KEY = "auth_info"; const AUTH_RESPONSE_KEY = "auth_info";
const CODE_VERIFIER_KEY = "auth_code_verifier"; const CODE_VERIFIER_KEY = "auth_code_verifier";
window.onload = function () { window.onload = function () {
try {
localStorage.removeItem(AUTH_RESPONSE_KEY); localStorage.removeItem(AUTH_RESPONSE_KEY);
localStorage.removeItem(CODE_VERIFIER_KEY); localStorage.removeItem(CODE_VERIFIER_KEY);
const params = new URLSearchParams(window.location.search) const params = new URLSearchParams(window.location.search)
@@ -15,8 +16,13 @@
} else { } else {
window.location.assign("/"); window.location.assign("/");
} }
} catch (error) {
console.error("[Logout Auth Redirect] Redirection failed:", error);
window.location.assign("/");
} }
</script> }
</script>
<title>Twake Mail</title>
</head> </head>
<body> <body>