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>
[](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)
[](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]