diff --git a/src/components/resource-policy/EditPolicyRulesSectionForm.tsx b/src/components/resource-policy/EditPolicyRulesSectionForm.tsx
index 13a344525..15669272b 100644
--- a/src/components/resource-policy/EditPolicyRulesSectionForm.tsx
+++ b/src/components/resource-policy/EditPolicyRulesSectionForm.tsx
@@ -61,6 +61,11 @@ import {
import { MAJOR_ASNS } from "@server/db/asns";
import { COUNTRIES } from "@server/db/countries";
+import {
+ REGIONS,
+ getRegionNameById,
+ isValidRegionId
+} from "@server/db/regions";
import {
isValidCIDR,
isValidIP,
@@ -210,6 +215,8 @@ export function EditPolicyRulesSectionForm({
const [openAddRuleCountrySelect, setOpenAddRuleCountrySelect] =
useState(false);
const [openAddRuleAsnSelect, setOpenAddRuleAsnSelect] = useState(false);
+ const [openAddRuleRegionSelect, setOpenAddRuleRegionSelect] =
+ useState(false);
const addRuleForm = useForm({
resolver: zodResolver(addRuleSchema),
@@ -235,7 +242,8 @@ export function EditPolicyRulesSectionForm({
IP: "IP",
CIDR: t("ipAddressRange"),
COUNTRY: t("country"),
- ASN: "ASN"
+ ASN: "ASN",
+ REGION: t("region")
}),
[t]
);
@@ -309,6 +317,14 @@ export function EditPolicyRulesSectionForm({
});
return;
}
+ if (data.match === "REGION" && !isValidRegionId(data.value)) {
+ toast({
+ variant: "destructive",
+ title: t("rulesErrorInvalidRegion"),
+ description: t("rulesErrorInvalidRegionDescription") || ""
+ });
+ return;
+ }
let priority = data.priority;
if (priority === undefined) {
@@ -378,6 +394,8 @@ export function EditPolicyRulesSectionForm({
return t("rulesMatchCountry");
case "ASN":
return "Enter an Autonomous System Number (e.g., AS15169 or 15169)";
+ case "REGION":
+ return t("rulesMatchRegion");
}
},
[t]
@@ -476,7 +494,13 @@ export function EditPolicyRulesSectionForm({
defaultValue={row.original.match}
disabled={readonly || row.original.fromPolicy}
onValueChange={(
- value: "CIDR" | "IP" | "PATH" | "COUNTRY" | "ASN"
+ value:
+ | "CIDR"
+ | "IP"
+ | "PATH"
+ | "COUNTRY"
+ | "ASN"
+ | "REGION"
) =>
updateRule(row.original.ruleId, {
match: value,
@@ -485,7 +509,9 @@ export function EditPolicyRulesSectionForm({
? "US"
: value === "ASN"
? "AS15169"
- : row.original.value
+ : value === "REGION"
+ ? "021"
+ : row.original.value
})
}
>
@@ -505,6 +531,11 @@ export function EditPolicyRulesSectionForm({
{RuleMatch.COUNTRY}
)}
+ {isMaxmindAvailable && (
+
+ {RuleMatch.REGION}
+
+ )}
{isMaxmindAsnAvailable && (
{RuleMatch.ASN}
@@ -666,6 +697,111 @@ export function EditPolicyRulesSectionForm({
+ ) : row.original.match === "REGION" ? (
+
+
+
+
+
+
+
+
+
+ {t("noRegionFound")}
+
+ {REGIONS.map((continent) => (
+
+
+ updateRule(
+ row.original.ruleId,
+ {
+ value: continent.id
+ }
+ )
+ }
+ >
+
+ {t(continent.name)} (
+ {continent.id})
+
+ {continent.includes.map(
+ (subregion) => (
+
+ updateRule(
+ row.original
+ .ruleId,
+ {
+ value: subregion.id
+ }
+ )
+ }
+ >
+
+ {t(subregion.name)}{" "}
+ ({subregion.id})
+
+ )
+ )}
+
+ ))}
+
+
+
+
) : (
)}
+ {isMaxmindAvailable && (
+
+ {
+ RuleMatch.REGION
+ }
+
+ )}
{isMaxmindAsnAvailable && (
{RuleMatch.ASN}
@@ -1240,6 +1383,160 @@ export function EditPolicyRulesSectionForm({
+ ) : addRuleForm.watch(
+ "match"
+ ) === "REGION" ? (
+
+
+
+
+
+
+
+
+
+ {t(
+ "noRegionFound"
+ )}
+
+ {REGIONS.map(
+ (
+ continent
+ ) => (
+
+ {
+ field.onChange(
+ continent.id
+ );
+ setOpenAddRuleRegionSelect(
+ false
+ );
+ }}
+ >
+
+ {t(
+ continent.name
+ )}{" "}
+ (
+ {
+ continent.id
+ }
+ )
+
+ {continent.includes.map(
+ (
+ subregion
+ ) => (
+ {
+ field.onChange(
+ subregion.id
+ );
+ setOpenAddRuleRegionSelect(
+ false
+ );
+ }}
+ >
+
+ {t(
+ subregion.name
+ )}{" "}
+ (
+ {
+ subregion.id
+ }
+ )
+
+ )
+ )}
+
+ )
+ )}
+
+
+
+
) : (