codeant-ai-for-open-source[bot] commented on code in PR #41338:
URL: https://github.com/apache/superset/pull/41338#discussion_r3491152276


##########
superset-frontend/src/features/alerts/components/NotificationMethod.tsx:
##########
@@ -190,6 +206,85 @@ type SlackOptionsType = {
   options: { label: string; value: string }[];
 }[];
 
+type EmailRecipientField = 'recipients' | 'cc' | 'bcc';
+
+type EmailRecipientOption = {
+  label: string;
+  value: string;
+};
+
+type RelatedUserOption = {
+  text: string;
+  value: number;
+  extra?: {
+    email?: string;
+  };
+};
+
+const emailRecipientSeparators = /[,;]/;
+
+const recipientStringToOptions = (value: string): EmailRecipientOption[] =>
+  value
+    .split(emailRecipientSeparators)
+    .map(recipient => recipient.trim())
+    .filter(Boolean)
+    .map(recipient => ({
+      label: recipient,
+      value: recipient,
+    }));
+
+const isEmailRecipientOption = (
+  option: unknown,
+): option is EmailRecipientOption => {
+  if (!option || typeof option !== 'object') {
+    return false;
+  }
+  const { value } = option as { value?: unknown };
+  return typeof value === 'string';
+};
+
+const normalizeEmailRecipientOptions = (
+  selected: unknown,
+): EmailRecipientOption[] =>
+  Array.isArray(selected) ? selected.filter(isEmailRecipientOption) : [];
+
+const emailRecipientOptionsToString = (selected: unknown) =>
+  normalizeEmailRecipientOptions(selected)
+    .map(option => option.value)
+    .join(',');
+
+const fetchEmailRecipientOptions = async (
+  filterValue: string,
+  page: number,
+  pageSize: number,
+) => {
+  const query = rison.encode({
+    filter: filterValue,
+    page,
+    page_size: pageSize,
+    order_column: 'username',
+    order_direction: 'asc',
+  });
+
+  const response = await SupersetClient.get({
+    endpoint: `/api/v1/report/related/owners?q=${query}`,

Review Comment:
   **Suggestion:** The owners lookup query is built with `rison.encode` and 
interpolated directly into the URL, which is not URI-safe for characters like 
`+`, `&`, and `#`. Recipient searches containing those characters can be parsed 
incorrectly by the backend and return wrong/no matches. Use URI-safe encoding 
for query params (for example `rison.encode_uri` or `encodeURIComponent` around 
the encoded string) before appending to `q=`. [api mismatch]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Alert email recipient owner lookup fails for '+' searches.
   - ⚠️ Incorrect owner suggestions when filter contains reserved characters.
   - ⚠️ Inconsistent encoding compared to createFetchRelated owner utilities.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open `AlertReportModal` in the UI, which renders `NotificationMethod` for 
each
   notification setting 
(`superset-frontend/src/features/alerts/AlertReportModal.tsx:20-33`
   and `:20-31` in the excerpt around lines 2740-2819). Choose a notification 
method of type
   `Email` so that the email recipient selector is rendered.
   
   
   
   2. In `NotificationMethod`, observe that for email methods the \"To\" 
recipient field is
   rendered as an `AsyncSelect` whose `options` prop is 
`fetchEmailRecipientOptions`
   
(`superset-frontend/src/features/alerts/components/NotificationMethod.tsx:600-679`,
 in
   particular lines 47-60 of that chunk where `AsyncSelect` is configured with
   `options={fetchEmailRecipientOptions}`).
   
   
   
   3. Type a search string containing reserved URL characters into the \"Email 
recipients\"
   field, for example `user+tag` or `user&tag`. `AsyncSelect` passes this input 
string as the
   `filterValue` argument into `fetchEmailRecipientOptions(filterValue, page, 
pageSize)`
   (`NotificationMethod.tsx:244-303`, the function starting at the
   `fetchEmailRecipientOptions` definition).
   
   
   
   4. Inside `fetchEmailRecipientOptions`, the filter is serialized using 
`rison.encode` and
   interpolated directly into the `q` query parameter without URI encoding
   (`NotificationMethod.tsx:261-270`). The resulting URL looks like
   `/api/v1/report/related/owners?q=(filter:'user+tag',page:0,...)`. When this 
request hits
   the backend, Flask/Werkzeug parses the query string and decodes `+` to a 
space inside the
   `q` parameter value (standard URL-decoding behavior), so the backend Rison 
parser sees
   `filter:'user tag'` instead of `filter:'user+tag'`. This leads to incorrect 
or empty
   matches from `/api/v1/report/related/owners`, so the AsyncSelect shows 
wrong/no owner
   options for such inputs. The fact that similar generic related-fetch helpers 
use
   `rison.encode_uri` for `q` (see `createFetchResourceMethod` in
   `superset-frontend/src/views/CRUD/utils.tsx:15-24` and `createFetchRelated` /
   `createFetchOwners` in the same file) further confirms that URI-safe 
encoding is expected
   for these `q` parameters.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=5ff08f3b15ab45eca39858ac50edb945&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=5ff08f3b15ab45eca39858ac50edb945&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/src/features/alerts/components/NotificationMethod.tsx
   **Line:** 261:270
   **Comment:**
        *Api Mismatch: The owners lookup query is built with `rison.encode` and 
interpolated directly into the URL, which is not URI-safe for characters like 
`+`, `&`, and `#`. Recipient searches containing those characters can be parsed 
incorrectly by the backend and return wrong/no matches. Use URI-safe encoding 
for query params (for example `rison.encode_uri` or `encodeURIComponent` around 
the encoded string) before appending to `q=`.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41338&comment_hash=11fcae870eca07a855cea6f9857f2cc8ccefba83cc6f915606400782259027c2&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41338&comment_hash=11fcae870eca07a855cea6f9857f2cc8ccefba83cc6f915606400782259027c2&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to