@@ -107,12 +107,21 @@ def search_aliases(query: str) -> EmailSearchResult:
107107
108108 @staticmethod
109109 def search_emails (query : str ) -> EmailSearchResult :
110- """Search for mailboxes, users, and partner users by exact match or POSIX regex."""
110+ """Search for mailboxes, users, and partner users by exact match or POSIX regex.
111+
112+ Only performs regex search if no exact match is found on user.email,
113+ mailbox.email, or partner_user.partner_email.
114+ """
111115 output = EmailSearchResult ()
112116 output .query = query
113117 output .search_type = EmailSearchResult .SEARCH_TYPE_EMAIL
114118
115- # Search mailboxes (eager load user relationship for template display)
119+ # Track if we found any exact match
120+ has_exact_match = False
121+
122+ # --- First pass: Check for exact matches ---
123+
124+ # Search mailboxes by exact match (eager load user relationship)
116125 mailbox = (
117126 Mailbox .filter_by (email = query ).options (joinedload (Mailbox .user )).first ()
118127 )
@@ -121,22 +130,9 @@ def search_emails(query: str) -> EmailSearchResult:
121130 output .mailboxes_found_by_regex = False
122131 output .mailbox_count = 1
123132 output .no_match = False
124- else :
125- # Try regex search for mailboxes
126- mailboxes = (
127- Mailbox .filter (Mailbox .email .op ("~" )(query ))
128- .options (joinedload (Mailbox .user ))
129- .order_by (Mailbox .id .desc ())
130- .limit (10 )
131- .all ()
132- )
133- if mailboxes :
134- output .mailboxes = mailboxes
135- output .mailboxes_found_by_regex = True
136- output .mailbox_count = len (mailboxes )
137- output .no_match = False
133+ has_exact_match = True
138134
139- # Search users
135+ # Search users by exact match (id or email)
140136 user = None
141137 try :
142138 user_id = int (query )
@@ -170,7 +166,41 @@ def search_emails(query: str) -> EmailSearchResult:
170166 .all ()
171167 )
172168 output .no_match = False
173- else :
169+ has_exact_match = True
170+
171+ # Search partner users by exact match
172+ proton_partner = None
173+ try :
174+ proton_partner = get_proton_partner ()
175+ partner_user = PartnerUser .filter_by (
176+ partner_id = proton_partner .id , partner_email = query
177+ ).first ()
178+ if partner_user :
179+ output .partner_users = [partner_user ]
180+ output .partner_users_found_by_regex = False
181+ output .no_match = False
182+ has_exact_match = True
183+ except ProtonPartnerNotSetUp :
184+ # Proton partner not configured, skip this search
185+ pass
186+
187+ # --- Second pass: Only do regex searches if no exact match was found ---
188+
189+ if not has_exact_match :
190+ # Try regex search for mailboxes
191+ mailboxes = (
192+ Mailbox .filter (Mailbox .email .op ("~" )(query ))
193+ .options (joinedload (Mailbox .user ))
194+ .order_by (Mailbox .id .desc ())
195+ .limit (10 )
196+ .all ()
197+ )
198+ if mailboxes :
199+ output .mailboxes = mailboxes
200+ output .mailboxes_found_by_regex = True
201+ output .mailbox_count = len (mailboxes )
202+ output .no_match = False
203+
174204 # Try regex search for users
175205 users = (
176206 User .filter (User .email .op ("~" )(query ))
@@ -183,29 +213,8 @@ def search_emails(query: str) -> EmailSearchResult:
183213 output .users_found_by_regex = True
184214 output .no_match = False
185215
186- # Also check user audit log by user_email
187- if not output .users :
188- user_audit_log = (
189- UserAuditLog .filter_by (user_email = query )
190- .order_by (UserAuditLog .created_at .desc ())
191- .all ()
192- )
193- if user_audit_log :
194- output .user_audit_log = user_audit_log
195- output .no_match = False
196-
197- # Search partner users
198- try :
199- proton_partner = get_proton_partner ()
200- partner_user = PartnerUser .filter_by (
201- partner_id = proton_partner .id , partner_email = query
202- ).first ()
203- if partner_user :
204- output .partner_users = [partner_user ]
205- output .partner_users_found_by_regex = False
206- output .no_match = False
207- else :
208- # Try regex search for partner users
216+ # Try regex search for partner users
217+ if proton_partner :
209218 partner_users = (
210219 PartnerUser .filter (
211220 PartnerUser .partner_id == proton_partner .id ,
@@ -219,9 +228,17 @@ def search_emails(query: str) -> EmailSearchResult:
219228 output .partner_users = partner_users
220229 output .partner_users_found_by_regex = True
221230 output .no_match = False
222- except ProtonPartnerNotSetUp :
223- # Proton partner not configured, skip this search
224- pass
231+
232+ # Also check user audit log by user_email if no users found
233+ if not output .users :
234+ user_audit_log = (
235+ UserAuditLog .filter_by (user_email = query )
236+ .order_by (UserAuditLog .created_at .desc ())
237+ .all ()
238+ )
239+ if user_audit_log :
240+ output .user_audit_log = user_audit_log
241+ output .no_match = False
225242
226243 return output
227244
0 commit comments