diff --git a/public/app/features/alerting/unified/components/notification-policies/EditNotificationPolicyForm.tsx b/public/app/features/alerting/unified/components/notification-policies/EditNotificationPolicyForm.tsx index f7eabb4896d..23e10a49f81 100644 --- a/public/app/features/alerting/unified/components/notification-policies/EditNotificationPolicyForm.tsx +++ b/public/app/features/alerting/unified/components/notification-policies/EditNotificationPolicyForm.tsx @@ -49,6 +49,38 @@ export interface AmRoutesExpandedFormProps { defaults?: Partial; } +function unwrapQuotes(value: string): { unquoted: string; hasQuotes: boolean } { + if (value.startsWith('"') && value.endsWith('"')) { + return { unquoted: value.slice(1, -1), hasQuotes: true }; + } + return { unquoted: value, hasQuotes: false }; +} + +const matcherValueValidator = { + containsReservedCharacter: (value: string) => { + const { unquoted, hasQuotes } = unwrapQuotes(value); + const reservedCharacters = ['{', '}', '!', '=', '~', '\\', '"']; + + // Reserved characters are allowed ONLY IF wrapped in quotes + if (hasQuotes) { + return true; + } + + return reservedCharacters.some((char) => unquoted.includes(char)) ? 'Contains reserved character.' : true; + }, + containsUnescapedCharacters: (value: string) => { + const unescapedQuotesRegex = /(?