TF-2305 Session::getOwnEmailAddress method to fetch the user email address from urn:ietf:params:jmap:principals imip mailto property if not present in the session username, which is the case for Cyrus

This commit is contained in:
Florent Azavant
2025-01-24 11:49:38 +01:00
committed by Dat H. Pham
parent 327af38fb0
commit 6720709a2e
23 changed files with 212 additions and 58 deletions
+1 -1
View File
@@ -451,7 +451,7 @@ abstract class BaseController extends GetxController
if (PlatformInfo.isMobile) { if (PlatformInfo.isMobile) {
showLogoutConfirmDialog( showLogoutConfirmDialog(
context: context, context: context,
username: session?.username.value ?? '', userAddress: session?.getOwnEmailAddress() ?? '',
onConfirmAction: () => _handleLogoutAction(session, accountId), onConfirmAction: () => _handleLogoutAction(session, accountId),
); );
} else { } else {
+2 -2
View File
@@ -6,7 +6,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
mixin LogoutMixin implements MessageDialogActionMixin { mixin LogoutMixin implements MessageDialogActionMixin {
void showLogoutConfirmDialog({ void showLogoutConfirmDialog({
required BuildContext context, required BuildContext context,
required String username, required String userAddress,
required Function? onConfirmAction, required Function? onConfirmAction,
}) { }) {
final appLocalizations = AppLocalizations.of(context); final appLocalizations = AppLocalizations.of(context);
@@ -33,7 +33,7 @@ mixin LogoutMixin implements MessageDialogActionMixin {
listTextSpan: [ listTextSpan: [
TextSpan(text: AppLocalizations.of(context).messageConfirmationLogout), TextSpan(text: AppLocalizations.of(context).messageConfirmationLogout),
TextSpan( TextSpan(
text: ' $username', text: ' $userAddress',
style: Theme.of(context).textTheme.bodyLarge?.copyWith( style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColor.colorTextBody, color: AppColor.colorTextBody,
fontSize: 15, fontSize: 15,
@@ -832,15 +832,15 @@ class ComposerController extends BaseController
required EmailActionType actionType, required EmailActionType actionType,
String? listPost, String? listPost,
}) { }) {
final userName = mailboxDashBoardController.sessionCurrent?.username.value; final senderEmailAddress = mailboxDashBoardController.sessionCurrent?.getOwnEmailAddress();
final isSender = presentationEmail.from final isSender = presentationEmail.from
.asList() .asList()
.any((element) => element.emailAddress.isNotEmpty && element.emailAddress == userName); .any((element) => element.emailAddress.isNotEmpty && element.emailAddress == senderEmailAddress);
final recipients = presentationEmail.generateRecipientsEmailAddressForComposer( final recipients = presentationEmail.generateRecipientsEmailAddressForComposer(
emailActionType: actionType, emailActionType: actionType,
isSender: isSender, isSender: isSender,
userName: userName, userName: senderEmailAddress,
listPost: listPost, listPost: listPost,
); );
@@ -1506,7 +1506,7 @@ class ComposerController extends BaseController
if (arguments.emailActionType == EmailActionType.editDraft) { if (arguments.emailActionType == EmailActionType.editDraft) {
return arguments.presentationEmail?.firstEmailAddressInFrom ?? ''; return arguments.presentationEmail?.firstEmailAddressInFrom ?? '';
} else { } else {
return mailboxDashBoardController.sessionCurrent?.username.value ?? ''; return mailboxDashBoardController.sessionCurrent?.getOwnEmailAddress() ?? '';
} }
} }
return ''; return '';
@@ -9,7 +9,7 @@ import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/email_action_type.dart'; import 'package:model/email/email_action_type.dart';
import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/email_address_extension.dart';
import 'package:model/extensions/username_extension.dart'; import 'package:model/extensions/session_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'; import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/identity_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/identity_extension.dart';
@@ -26,7 +26,7 @@ extension CreateEmailRequestExtension on CreateEmailRequest {
if (identity?.email?.isNotEmpty == true) { if (identity?.email?.isNotEmpty == true) {
return { identity!.toEmailAddress() }; return { identity!.toEmailAddress() };
} else { } else {
return { session.username.toEmailAddress() }; return { EmailAddress(null, session.getOwnEmailAddress()) };
} }
} }
@@ -34,7 +34,7 @@ extension CreateEmailRequestExtension on CreateEmailRequest {
if (emailActionType == EmailActionType.editDraft && fromSender.isNotEmpty) { if (emailActionType == EmailActionType.editDraft && fromSender.isNotEmpty) {
return fromSender.first.emailAddress; return fromSender.first.emailAddress;
} else { } else {
return session.username.value; return session.getOwnEmailAddress();
} }
} }
@@ -42,7 +42,7 @@ extension CreateEmailRequestExtension on CreateEmailRequest {
if (identity?.replyTo?.isNotEmpty == true) { if (identity?.replyTo?.isNotEmpty == true) {
return identity!.replyTo!.toSet(); return identity!.replyTo!.toSet();
} else { } else {
return { session.username.toEmailAddress() }; return { EmailAddress(null, session.getOwnEmailAddress()) };
} }
} }
@@ -1370,7 +1370,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
return; return;
} }
final receiverEmailAddress = _getReceiverEmailAddress(currentEmail!) ?? session!.username.value; final receiverEmailAddress = _getReceiverEmailAddress(currentEmail!) ?? session!.getOwnEmailAddress();
log('SingleEmailController::_handleSendReceiptToSenderAction():receiverEmailAddress: $receiverEmailAddress'); log('SingleEmailController::_handleSendReceiptToSenderAction():receiverEmailAddress: $receiverEmailAddress');
final mdnToSender = _generateMDN(context, currentEmail!, receiverEmailAddress); final mdnToSender = _generateMDN(context, currentEmail!, receiverEmailAddress);
final sendReceiptRequest = SendReceiptToSenderRequest( final sendReceiptRequest = SendReceiptToSenderRequest(
@@ -2243,8 +2243,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
listEmailAddressAttendees.addAll(listEmailAddress); listEmailAddressAttendees.addAll(listEmailAddress);
final username = mailboxDashBoardController.sessionCurrent?.username.value ?? ''; final currentUserEmail = mailboxDashBoardController.sessionCurrent?.getOwnEmailAddress() ?? '';
final listEmailAddressMailTo = listEmailAddressAttendees.removeInvalidEmails(username); final listEmailAddressMailTo = listEmailAddressAttendees.removeInvalidEmails(currentUserEmail);
log('SingleEmailController::handleMailToAttendees: listEmailAddressMailTo = $listEmailAddressMailTo'); log('SingleEmailController::handleMailToAttendees: listEmailAddressMailTo = $listEmailAddressMailTo');
mailboxDashBoardController.goToComposer( mailboxDashBoardController.goToComposer(
ComposerArguments.fromMailtoUri(listEmailAddress: listEmailAddressMailTo) ComposerArguments.fromMailtoUri(listEmailAddress: listEmailAddressMailTo)
@@ -5,7 +5,6 @@ import 'package:contact/contact/model/autocomplete_capability.dart';
import 'package:contact/contact/model/capability_contact.dart'; import 'package:contact/contact/model/capability_contact.dart';
import 'package:core/presentation/extensions/uri_extension.dart'; import 'package:core/presentation/extensions/uri_extension.dart';
import 'package:core/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/http/converter/state_converter.dart'; import 'package:jmap_dart_client/http/converter/state_converter.dart';
import 'package:jmap_dart_client/http/converter/user_name_converter.dart'; import 'package:jmap_dart_client/http/converter/user_name_converter.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
@@ -61,13 +60,7 @@ extension SessionExtensions on Session {
String get internalDomain { String get internalDomain {
try { try {
if (GetUtils.isEmail(username.value)) { return getOwnEmailAddress().split('@').last;
return username.value.split('@').last;
} else if (GetUtils.isEmail(personalAccount.name.value)) {
return personalAccount.name.value.split('@').last;
} else {
return '';
}
} catch (e) { } catch (e) {
logError('SessionExtensions::internalDomain: Exception: $e'); logError('SessionExtensions::internalDomain: Exception: $e');
return ''; return '';
@@ -375,8 +375,8 @@ class IdentityCreatorController extends BaseController with DragDropFileMixin im
void _setDefaultEmailAddressList() { void _setDefaultEmailAddressList() {
listEmailAddressOfReplyTo.add(noneEmailAddress); listEmailAddressOfReplyTo.add(noneEmailAddress);
if (session?.username.value.isNotEmpty == true) { if (session?.getOwnEmailAddress() != null) {
final userEmailAddress = EmailAddress(null, session?.username.value); final userEmailAddress = EmailAddress(null, session?.getOwnEmailAddress());
listEmailAddressDefault.add(userEmailAddress); listEmailAddressDefault.add(userEmailAddress);
listEmailAddressOfReplyTo.addAll(listEmailAddressDefault); listEmailAddressOfReplyTo.addAll(listEmailAddressDefault);
} }
@@ -3,6 +3,7 @@ import 'package:core/utils/direction_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart'; import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/base_mailbox_view.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/base_mailbox_view.dart';
@@ -224,7 +225,7 @@ class MailboxView extends BaseMailboxView {
} }
return UserInformationWidget( return UserInformationWidget(
userName: controller.mailboxDashBoardController.accountId.value != null userName: controller.mailboxDashBoardController.accountId.value != null
? controller.mailboxDashBoardController.sessionCurrent?.username ? UserName(controller.mailboxDashBoardController.sessionCurrent!.getOwnEmailAddress())
: null, : null,
subtitle: AppLocalizations.of(context).manage_account, subtitle: AppLocalizations.of(context).manage_account,
onSubtitleClick: controller.mailboxDashBoardController.goToSettings, onSubtitleClick: controller.mailboxDashBoardController.goToSettings,
@@ -2,6 +2,7 @@ import 'package:core/core.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/widget/application_logo_with_text_widget.dart'; import 'package:tmail_ui_user/features/base/widget/application_logo_with_text_widget.dart';
import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart'; import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart';
@@ -141,7 +142,7 @@ class MailboxView extends BaseMailboxView {
if (!controller.responsiveUtils.isDesktop(context)) if (!controller.responsiveUtils.isDesktop(context))
Obx(() => UserInformationWidget( Obx(() => UserInformationWidget(
userName: controller.mailboxDashBoardController.accountId.value != null userName: controller.mailboxDashBoardController.accountId.value != null
? controller.mailboxDashBoardController.sessionCurrent?.username ? UserName(controller.mailboxDashBoardController.sessionCurrent!.getOwnEmailAddress())
: null, : null,
subtitle: AppLocalizations.of(context).manage_account, subtitle: AppLocalizations.of(context).manage_account,
onSubtitleClick: controller.mailboxDashBoardController.goToSettings, onSubtitleClick: controller.mailboxDashBoardController.goToSettings,
@@ -3125,7 +3125,7 @@ class MailboxDashBoardController extends ReloadableController
isRecoveringDeletedMessage.value = true; isRecoveringDeletedMessage.value = true;
} }
String get userEmail => sessionCurrent?.username.value ?? ''; String get userEmail => sessionCurrent?.getOwnEmailAddress() ?? '';
Future<void> _removeComposerCacheOnWeb() async { Future<void> _removeComposerCacheOnWeb() async {
await _removeComposerCacheOnWebInteractor.execute(); await _removeComposerCacheOnWebInteractor.execute();
@@ -3162,7 +3162,7 @@ class MailboxDashBoardController extends ReloadableController
position, position,
popupMenuUserSettingActionTile( popupMenuUserSettingActionTile(
context, context,
sessionCurrent?.username, sessionCurrent?.getOwnEmailAddress(),
onLogoutAction: () { onLogoutAction: () {
popBack(); popBack();
logout( logout(
@@ -9,7 +9,6 @@ import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart'; import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_comparator.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_comparator.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart';
@@ -17,6 +16,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:model/email/presentation_email.dart'; import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/email_filter_condition_extension.dart'; import 'package:model/extensions/email_filter_condition_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/date_range_picker_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/date_range_picker_mixin.dart';
@@ -98,7 +98,7 @@ class SearchController extends BaseController with DateRangePickerMixin {
sort: <Comparator>{}..add( sort: <Comparator>{}..add(
EmailComparator(EmailComparatorProperty.receivedAt) EmailComparator(EmailComparatorProperty.receivedAt)
..setIsAscending(false)), ..setIsAscending(false)),
filter: _mappingToFilterOnSuggestionForm(userName: session.username, query: query), filter: _mappingToFilterOnSuggestionForm(currentUserEmail: session.getOwnEmailAddress(), query: query),
properties: EmailUtils.getPropertiesForEmailGetMethod(session, accountId), properties: EmailUtils.getPropertiesForEmailGetMethod(session, accountId),
).then((result) => result.fold( ).then((result) => result.fold(
(failure) => <PresentationEmail>[], (failure) => <PresentationEmail>[],
@@ -108,7 +108,7 @@ class SearchController extends BaseController with DateRangePickerMixin {
)); ));
} }
Filter? _mappingToFilterOnSuggestionForm({required String query, required UserName userName}) { Filter? _mappingToFilterOnSuggestionForm({required String query, required String currentUserEmail}) {
log('SearchController::_mappingToFilterOnSuggestionForm():query: $query'); log('SearchController::_mappingToFilterOnSuggestionForm():query: $query');
final filterCondition = EmailFilterCondition( final filterCondition = EmailFilterCondition(
text: query.isNotEmpty == true ? query : null, text: query.isNotEmpty == true ? query : null,
@@ -122,7 +122,7 @@ class SearchController extends BaseController with DateRangePickerMixin {
? true ? true
: null, : null,
from: listFilterOnSuggestionForm.contains(QuickSearchFilter.fromMe) from: listFilterOnSuggestionForm.contains(QuickSearchFilter.fromMe)
? userName.value ? currentUserEmail
: null, : null,
hasKeyword: listFilterOnSuggestionForm.contains(QuickSearchFilter.starred) hasKeyword: listFilterOnSuggestionForm.contains(QuickSearchFilter.starred)
? KeyWordIdentifier.emailFlagged.value ? KeyWordIdentifier.emailFlagged.value
@@ -134,7 +134,7 @@ class SearchController extends BaseController with DateRangePickerMixin {
: null; : null;
} }
void applyFilterSuggestionToSearchFilter(UserName? userName) { void applyFilterSuggestionToSearchFilter(String? currentUserEmail) {
final receiveTime = listFilterOnSuggestionForm.contains(QuickSearchFilter.last7Days) final receiveTime = listFilterOnSuggestionForm.contains(QuickSearchFilter.last7Days)
? EmailReceiveTimeType.last7Days ? EmailReceiveTimeType.last7Days
: EmailReceiveTimeType.allTime; : EmailReceiveTimeType.allTime;
@@ -142,11 +142,11 @@ class SearchController extends BaseController with DateRangePickerMixin {
final hasAttachment = listFilterOnSuggestionForm.contains(QuickSearchFilter.hasAttachment) ? true : false; final hasAttachment = listFilterOnSuggestionForm.contains(QuickSearchFilter.hasAttachment) ? true : false;
var listFromAddress = searchEmailFilter.value.from; var listFromAddress = searchEmailFilter.value.from;
if (userName != null) { if (currentUserEmail != null) {
if (listFilterOnSuggestionForm.contains(QuickSearchFilter.fromMe)) { if (listFilterOnSuggestionForm.contains(QuickSearchFilter.fromMe)) {
listFromAddress.add(userName.value); listFromAddress.add(currentUserEmail);
} else { } else {
listFromAddress.remove(userName.value); listFromAddress.remove(currentUserEmail);
} }
} }
@@ -5,6 +5,7 @@ import 'package:flutter_portal/flutter_portal.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart'; import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/extensions/username_extension.dart'; import 'package:model/extensions/username_extension.dart';
import 'package:tmail_ui_user/features/base/widget/popup_item_no_icon_widget.dart'; import 'package:tmail_ui_user/features/base/widget/popup_item_no_icon_widget.dart';
import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart'; import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart';
@@ -540,7 +541,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
final searchEmailFilter = controller.searchController.searchEmailFilter.value; final searchEmailFilter = controller.searchController.searchEmailFilter.value;
final sortOrderType = controller.searchController.sortOrderFiltered; final sortOrderType = controller.searchController.sortOrderFiltered;
final listAddressOfFrom = controller.searchController.listAddressOfFromFiltered; final listAddressOfFrom = controller.searchController.listAddressOfFromFiltered;
final userName = controller.sessionCurrent?.username; final currentUserEmail = controller.sessionCurrent?.getOwnEmailAddress();
final startDate = controller.searchController.startDateFiltered; final startDate = controller.searchController.startDateFiltered;
final endDate = controller.searchController.endDateFiltered; final endDate = controller.searchController.endDateFiltered;
final receiveTimeType = controller.searchController.receiveTimeFiltered; final receiveTimeType = controller.searchController.receiveTimeFiltered;
@@ -551,7 +552,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
context, context,
searchEmailFilter, searchEmailFilter,
sortOrderType, sortOrderType,
userName); currentUserEmail);
EdgeInsetsGeometry? buttonPadding; EdgeInsetsGeometry? buttonPadding;
if (searchFilter != QuickSearchFilter.sortBy) { if (searchFilter != QuickSearchFilter.sortBy) {
@@ -570,7 +571,6 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
sortOrderType: sortOrderType, sortOrderType: sortOrderType,
listAddressOfFrom: listAddressOfFrom, listAddressOfFrom: listAddressOfFrom,
listAddressOfTo: listAddressOfTo, listAddressOfTo: listAddressOfTo,
userName: userName,
mailbox: mailbox, mailbox: mailbox,
buttonPadding: buttonPadding, buttonPadding: buttonPadding,
onSelectSearchFilterAction: _onSelectSearchFilterAction, onSelectSearchFilterAction: _onSelectSearchFilterAction,
@@ -4,7 +4,6 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/popup_menu/popup_menu_item_widget.dart'; import 'package:core/presentation/views/popup_menu/popup_menu_item_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
mixin UserSettingPopupMenuMixin { mixin UserSettingPopupMenuMixin {
@@ -12,14 +11,14 @@ mixin UserSettingPopupMenuMixin {
List<PopupMenuEntry> popupMenuUserSettingActionTile( List<PopupMenuEntry> popupMenuUserSettingActionTile(
BuildContext context, BuildContext context,
UserName? userName, String? currentUserEmail,
{ {
Function? onLogoutAction, Function? onLogoutAction,
Function? onSettingAction Function? onSettingAction
} }
) { ) {
return [ return [
if (userName != null) if(currentUserEmail != null)
PopupMenuItem( PopupMenuItem(
enabled: false, enabled: false,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
@@ -28,7 +27,7 @@ mixin UserSettingPopupMenuMixin {
child: ListTile( child: ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 20), contentPadding: const EdgeInsets.symmetric(horizontal: 20),
title: SelectableText( title: SelectableText(
userName.value, currentUserEmail,
maxLines: 1, maxLines: 1,
style: const TextStyle( style: const TextStyle(
fontSize: 15, fontSize: 15,
@@ -126,7 +126,7 @@ enum QuickSearchFilter {
BuildContext context, BuildContext context,
SearchEmailFilter searchFilter, SearchEmailFilter searchFilter,
EmailSortOrderType sortOrderType, EmailSortOrderType sortOrderType,
UserName? userName, String? currentUserEmail,
) { ) {
switch (this) { switch (this) {
case QuickSearchFilter.hasAttachment: case QuickSearchFilter.hasAttachment:
@@ -135,8 +135,8 @@ enum QuickSearchFilter {
return searchFilter.emailReceiveTimeType == EmailReceiveTimeType.last7Days; return searchFilter.emailReceiveTimeType == EmailReceiveTimeType.last7Days;
case QuickSearchFilter.fromMe: case QuickSearchFilter.fromMe:
return searchFilter.from.length == 1 && return searchFilter.from.length == 1 &&
userName?.value.isNotEmpty == true && currentUserEmail?.isNotEmpty == true &&
userName?.value == searchFilter.from.first; currentUserEmail == searchFilter.from.first;
case QuickSearchFilter.sortBy: case QuickSearchFilter.sortBy:
return sortOrderType != EmailSortOrderType.mostRecent; return sortOrderType != EmailSortOrderType.mostRecent;
case QuickSearchFilter.dateTime: case QuickSearchFilter.dateTime:
@@ -4,7 +4,6 @@ import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart';
@@ -31,7 +30,6 @@ class SearchFilterButton extends StatelessWidget {
final DateTime? endDate; final DateTime? endDate;
final Set<String>? listAddressOfFrom; final Set<String>? listAddressOfFrom;
final Set<String>? listAddressOfTo; final Set<String>? listAddressOfTo;
final UserName? userName;
final PresentationMailbox? mailbox; final PresentationMailbox? mailbox;
final Color? backgroundColor; final Color? backgroundColor;
final EdgeInsetsGeometry? buttonPadding; final EdgeInsetsGeometry? buttonPadding;
@@ -50,7 +48,6 @@ class SearchFilterButton extends StatelessWidget {
this.endDate, this.endDate,
this.listAddressOfFrom, this.listAddressOfFrom,
this.listAddressOfTo, this.listAddressOfTo,
this.userName,
this.mailbox, this.mailbox,
this.backgroundColor, this.backgroundColor,
this.buttonPadding, this.buttonPadding,
@@ -67,7 +64,6 @@ class SearchFilterButton extends StatelessWidget {
endDate: startDate, endDate: startDate,
sortOrderType: sortOrderType, sortOrderType: sortOrderType,
listAddressOfFrom: listAddressOfFrom, listAddressOfFrom: listAddressOfFrom,
userName: userName,
mailbox: mailbox, mailbox: mailbox,
listAddressOfTo: listAddressOfTo, listAddressOfTo: listAddressOfTo,
); );
@@ -15,6 +15,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/email/presentation_email.dart'; import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
@@ -146,7 +147,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
if (queryString.isNotEmpty || _searchController.listFilterOnSuggestionForm.isNotEmpty) { if (queryString.isNotEmpty || _searchController.listFilterOnSuggestionForm.isNotEmpty) {
_searchController.clearSearchFilter(); _searchController.clearSearchFilter();
_searchController.applyFilterSuggestionToSearchFilter(_dashBoardController.sessionCurrent?.username); _searchController.applyFilterSuggestionToSearchFilter(_dashBoardController.sessionCurrent?.getOwnEmailAddress());
_dashBoardController.searchEmailByQueryString(queryString); _dashBoardController.searchEmailByQueryString(queryString);
} else { } else {
_dashBoardController.clearSearchEmail(); _dashBoardController.clearSearchEmail();
@@ -166,7 +167,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
_searchController.searchFocus.unfocus(); _searchController.searchFocus.unfocus();
_searchController.enableSearch(); _searchController.enableSearch();
_searchController.clearSearchFilter(); _searchController.clearSearchFilter();
_searchController.applyFilterSuggestionToSearchFilter(_dashBoardController.sessionCurrent?.username); _searchController.applyFilterSuggestionToSearchFilter(_dashBoardController.sessionCurrent?.getOwnEmailAddress());
_dashBoardController.searchEmailByQueryString(recent.value); _dashBoardController.searchEmailByQueryString(recent.value);
} }
@@ -363,7 +363,7 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet
position, position,
popupMenuUserSettingActionTile( popupMenuUserSettingActionTile(
context, context,
sessionCurrent?.username, sessionCurrent?.getOwnEmailAddress(),
onLogoutAction: () { onLogoutAction: () {
popBack(); popBack();
logout(context, sessionCurrent, accountId.value); logout(context, sessionCurrent, accountId.value);
@@ -2,6 +2,8 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/utils/platform_info.dart'; import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart'; import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
@@ -20,7 +22,7 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
child: Column(children: [ child: Column(children: [
Obx(() => UserInformationWidget( Obx(() => UserInformationWidget(
userName: controller.manageAccountDashboardController.accountId.value != null userName: controller.manageAccountDashboardController.accountId.value != null
? controller.manageAccountDashboardController.sessionCurrent?.username ? UserName(controller.manageAccountDashboardController.sessionCurrent!.getOwnEmailAddress())
: null, : null,
padding: SettingsUtils.getPaddingInFirstLevel(context, controller.responsiveUtils), padding: SettingsUtils.getPaddingInFirstLevel(context, controller.responsiveUtils),
titlePadding: const EdgeInsetsDirectional.only(start: 16))), titlePadding: const EdgeInsetsDirectional.only(start: 16))),
@@ -250,7 +250,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
final searchEmailFilter = controller.searchEmailFilter.value; final searchEmailFilter = controller.searchEmailFilter.value;
final sortOrderType = controller.emailSortOrderType.value; final sortOrderType = controller.emailSortOrderType.value;
final listAddressOfFrom = controller.listAddressOfFromFiltered; final listAddressOfFrom = controller.listAddressOfFromFiltered;
final userName = controller.session?.username; final currentUserEmail = controller.session?.getOwnEmailAddress();
final startDate = controller.startDateFiltered; final startDate = controller.startDateFiltered;
final endDate = controller.endDateFiltered; final endDate = controller.endDateFiltered;
final receiveTimeType = controller.receiveTimeFiltered; final receiveTimeType = controller.receiveTimeFiltered;
@@ -261,7 +261,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
context, context,
searchEmailFilter, searchEmailFilter,
sortOrderType, sortOrderType,
userName); currentUserEmail);
return SearchFilterButton( return SearchFilterButton(
key: Key('mobile_${searchFilter.name}_search_filter_button'), key: Key('mobile_${searchFilter.name}_search_filter_button'),
@@ -275,7 +275,6 @@ class SearchEmailView extends GetWidget<SearchEmailController>
sortOrderType: sortOrderType, sortOrderType: sortOrderType,
listAddressOfFrom: listAddressOfFrom, listAddressOfFrom: listAddressOfFrom,
listAddressOfTo: listAddressOfTo, listAddressOfTo: listAddressOfTo,
userName: userName,
mailbox: mailbox, mailbox: mailbox,
backgroundColor: searchFilter.getMobileBackgroundColor(isSelected: isSelected), backgroundColor: searchFilter.getMobileBackgroundColor(isSelected: isSelected),
onSelectSearchFilterAction: _onSelectSearchFilterAction, onSelectSearchFilterAction: _onSelectSearchFilterAction,
@@ -0,0 +1 @@
class UnknownAddressException implements Exception {}
@@ -2,15 +2,20 @@
import 'dart:ui'; import 'dart:ui';
import 'package:core/presentation/extensions/uri_extension.dart'; import 'package:core/presentation/extensions/uri_extension.dart';
import 'package:get/get_utils/src/extensions/string_extensions.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/capability/calendar_event_capability.dart'; import 'package:jmap_dart_client/jmap/core/capability/calendar_event_capability.dart';
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
import 'package:jmap_dart_client/jmap/core/capability/capability_properties.dart'; import 'package:jmap_dart_client/jmap/core/capability/capability_properties.dart';
import 'package:jmap_dart_client/jmap/core/capability/default_capability.dart';
import 'package:jmap_dart_client/jmap/core/capability/empty_capability.dart'; import 'package:jmap_dart_client/jmap/core/capability/empty_capability.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:model/error_type_handler/account_exception.dart'; import 'package:model/error_type_handler/account_exception.dart';
import 'package:model/error_type_handler/unknown_address_exception.dart';
import 'package:model/error_type_handler/unknown_uri_exception.dart'; import 'package:model/error_type_handler/unknown_uri_exception.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:model/principals/capability_principals.dart';
import 'package:uri/uri.dart'; import 'package:uri/uri.dart';
extension SessionExtension on Session { extension SessionExtension on Session {
@@ -66,6 +71,38 @@ extension SessionExtension on Session {
} }
} }
String getOwnEmailAddress() {
return username.value.isEmail ? username.value
: _getOwnEmailAddressFromPersonalAccount()
?? _getOwnEmailAddressFromPrincipalsCapability()
?? (throw UnknownAddressException());
}
String? _getOwnEmailAddressFromPersonalAccount() {
try {
return personalAccount.name.value.isEmail ? personalAccount.name.value : null;
} catch (_) {
return null;
}
}
String? _getOwnEmailAddressFromPrincipalsCapability() {
try {
var principalsCapability = getCapabilityProperties<DefaultCapability>(AccountId(Id(username.value)), capabilityPrincipals);
final sendTo = principalsCapability?.properties?['urn:ietf:params:jmap:calendars']?['sendTo'];
if (sendTo is Map<String, dynamic>) {
final wrappedAddress = sendTo['imip'];
if (wrappedAddress is String && wrappedAddress.startsWith('mailto:')) {
String address = wrappedAddress.substring("mailto:".length);
return address.isEmail ? address : null;
}
}
} catch (_) {
return null;
}
return null;
}
JmapAccount get personalAccount { JmapAccount get personalAccount {
if (accounts.isNotEmpty) { if (accounts.isNotEmpty) {
final listPersonalAccount = accounts.entries final listPersonalAccount = accounts.entries
@@ -0,0 +1,3 @@
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
final capabilityPrincipals = CapabilityIdentifier(Uri.parse('urn:ietf:params:jmap:principals'));
@@ -5,12 +5,15 @@ import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/account/account.dart'; import 'package:jmap_dart_client/jmap/core/account/account.dart';
import 'package:jmap_dart_client/jmap/core/capability/calendar_event_capability.dart'; import 'package:jmap_dart_client/jmap/core/capability/calendar_event_capability.dart';
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
import 'package:jmap_dart_client/jmap/core/capability/default_capability.dart';
import 'package:jmap_dart_client/jmap/core/capability/empty_capability.dart'; import 'package:jmap_dart_client/jmap/core/capability/empty_capability.dart';
import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/error_type_handler/unknown_address_exception.dart';
import 'package:model/extensions/session_extension.dart'; import 'package:model/extensions/session_extension.dart';
import 'package:model/principals/capability_principals.dart';
void main() { void main() {
final accountId = AccountId(Id('123abc')); final accountId = AccountId(Id('123abc'));
@@ -80,7 +83,7 @@ void main() {
test( test(
'should return null ' 'should return null '
'when calendar event capability supportes no language', 'when calendar event capability supports no language',
() { () {
// arrange // arrange
final calendarEventCapability = CalendarEventCapability(); final calendarEventCapability = CalendarEventCapability();
@@ -165,4 +168,122 @@ void main() {
expect(calendarEventLanguage, 'vi'); expect(calendarEventLanguage, 'vi');
}); });
}); });
group('getOwnEmailAddress test:', () {
test(
'should return username.value '
'when it is a valid email and principals capability is absent',
() {
// arrange
final session = Session({}, {}, {}, UserName('test@example.com'), Uri(), Uri(), Uri(), Uri(), State(''),);
// act
final emailAddress = session.getOwnEmailAddress();
// assert
expect(emailAddress, 'test@example.com');
});
test(
'should return username.value'
'when it is a valid email and principals capability is present but has no address',
() {
// arrange
final session = Session(
{capabilityPrincipals: DefaultCapability({})},
{}, {}, UserName('test@example.com'), Uri(), Uri(), Uri(), Uri(), State(''),
);
// act
final emailAddress = session.getOwnEmailAddress();
// assert
expect(emailAddress, 'test@example.com');
});
test(
'should return username.value'
'when it is a valid email and principals capability is present with an address',
() {
// arrange
final session = Session(
{capabilityPrincipals: DefaultCapability({'key': {'subKey': 'mailto:another@example.com'}})},
{}, {}, UserName('test@example.com'), Uri(), Uri(), Uri(), Uri(), State(''),
);
// act
final emailAddress = session.getOwnEmailAddress();
// assert
expect(emailAddress, 'test@example.com');
});
test(
'should throw exception'
'when username is not a valid email and principals capability is absent',
() {
// arrange
final session = Session({}, {}, {}, UserName('notAnEmail'), Uri(), Uri(), Uri(), Uri(), State(''));
// assert
expect(() => session.getOwnEmailAddress(), throwsA(isA<UnknownAddressException>()));
});
test(
'should return null'
'when username is not a valid email and principals capability is present but has no address',
() {
// arrange
final session = Session(
{capabilityPrincipals: DefaultCapability({})},
{}, {}, UserName('notAnEmail'), Uri(), Uri(), Uri(), Uri(), State(''),
);
// assert
expect(() => session.getOwnEmailAddress(), throwsA(isA<UnknownAddressException>()));
});
test(
'should return null'
'when username is not a valid email and principals capability is present but has no valid address',
() {
// arrange
final session = Session(
{capabilityPrincipals: DefaultCapability({'key': {'subKey': 'test@example.com'}})},
{}, {}, UserName('notAnEmail'), Uri(), Uri(), Uri(), Uri(), State(''),
);
// assert
expect(() => session.getOwnEmailAddress(), throwsA(isA<UnknownAddressException>()));
});
test(
'should return email address from principals capability'
'when username is not a valid email and principals capability is present with an address',
() {
// arrange
final capability = DefaultCapability({
"currentUserPrincipalId": "bob",
"urn:ietf:params:jmap:calendars": {
"accountId": "bob",
"account": null,
"mayGetAvailability": true,
"sendTo": {
"imip": "mailto:bob@example.com"
}
}
});
final session = Session(
{capabilityPrincipals: capability},
{}, {}, UserName('notAnEmail'), Uri(), Uri(), Uri(), Uri(), State(''),
);
// act
final emailAddress = session.getOwnEmailAddress();
// assert
expect(emailAddress, 'bob@example.com');
});
});
} }