Merge pull request #3342 from Fredkiss3/feat/geoip-country-is-not-rule

feat: add country `is not` rule in resource policies
This commit is contained in:
Milo Schwartz 2026-07-07 21:18:43 -04:00 committed by GitHub
commit 1e7863ce4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 110 additions and 49 deletions

View file

@ -75,6 +75,7 @@ import {
type PolicyAccessRule
} from "./policy-access-rule-utils";
import { countryCodeToFlagEmoji } from "@app/lib/countryCodeToFlagEmoji";
import type { readonly } from "zod";
export type PolicyAccessRulesTableProps = {
rules: PolicyAccessRule[];
@ -106,7 +107,7 @@ function getColumnClassName(columnId: string) {
return "w-42 max-w-42";
}
if (columnId === "match") {
return "w-36 max-w-36";
return "w-42 max-w-42";
}
return "";
}
@ -230,6 +231,7 @@ export function PolicyAccessRulesTable({
IP: "IP",
CIDR: t("ipAddressRange"),
COUNTRY: t("country"),
COUNTRY_IS_NOT: t("countryIsNot"),
ASN: "ASN",
REGION: t("region")
}),
@ -442,13 +444,15 @@ export function PolicyAccessRulesTable({
| "IP"
| "PATH"
| "COUNTRY"
| "COUNTRY_IS_NOT"
| "ASN"
| "REGION"
) =>
updateRule(row.original.ruleId, {
match: value,
value:
value === "COUNTRY"
value === "COUNTRY" ||
value === "COUNTRY_IS_NOT"
? "US"
: value === "ASN"
? "AS15169"
@ -458,7 +462,7 @@ export function PolicyAccessRulesTable({
})
}
>
<SelectTrigger className="h-8 w-full min-w-0">
<SelectTrigger className="h-8 w-36 min-w-0">
<SelectValue />
</SelectTrigger>
<SelectContent>
@ -470,9 +474,14 @@ export function PolicyAccessRulesTable({
{RuleMatch.CIDR}
</SelectItem>
{isMaxmindAvailable && (
<SelectItem value="COUNTRY">
{RuleMatch.COUNTRY}
</SelectItem>
<>
<SelectItem value="COUNTRY">
{RuleMatch.COUNTRY}
</SelectItem>
<SelectItem value="COUNTRY_IS_NOT">
{RuleMatch.COUNTRY_IS_NOT}
</SelectItem>
</>
)}
{includeRegionMatch && isMaxmindAvailable && (
<SelectItem value="REGION">
@ -494,14 +503,16 @@ export function PolicyAccessRulesTable({
cell: ({ row }) => {
let selectedCountry: (typeof COUNTRIES)[number] | undefined;
if (
row.original.match === "COUNTRY" &&
(row.original.match === "COUNTRY" ||
row.original.match === "COUNTRY_IS_NOT") &&
row.original.value
) {
selectedCountry = COUNTRIES.find(
(c) => c.code === row.original.value
);
}
return row.original.match === "COUNTRY" ? (
return row.original.match === "COUNTRY" ||
row.original.match === "COUNTRY_IS_NOT" ? (
<Popover>
<PopoverTrigger asChild>
<Button

View file

@ -17,6 +17,7 @@ export const POLICY_RULE_MATCH_TYPES = [
"IP",
"PATH",
"COUNTRY",
"COUNTRY_IS_NOT",
"ASN",
"REGION"
] as const;
@ -78,6 +79,7 @@ export function createPolicyRuleValueSchema(t: TranslateFn, match: string) {
message: t("rulesErrorInvalidRegionDescription")
});
case "COUNTRY":
case "COUNTRY_IS_NOT":
return required.refine(
(value) => COUNTRIES.some((country) => country.code === value),
{ message: t("rulesErrorInvalidCountryDescription") }