🚧 add country is not rule

This commit is contained in:
Fred KISSIE
2026-06-25 20:28:57 +02:00
parent f8591f27c5
commit e54bd25516
8 changed files with 40 additions and 9 deletions
+1
View File
@@ -2431,6 +2431,7 @@
"noRemoteExitNodesAvailableDescription": "No nodes are available for this organization. Create a node first to use local sites.", "noRemoteExitNodesAvailableDescription": "No nodes are available for this organization. Create a node first to use local sites.",
"exitNode": "Exit Node", "exitNode": "Exit Node",
"country": "Country", "country": "Country",
"countryIsNot": "Country Is Not",
"rulesMatchCountry": "Currently based on source IP", "rulesMatchCountry": "Currently based on source IP",
"region": "Region", "region": "Region",
"selectRegion": "Select region", "selectRegion": "Select region",
+10 -1
View File
@@ -981,7 +981,15 @@ export const resourcePolicyRules = pgTable("resourcePolicyRules", {
priority: integer("priority").notNull(), priority: integer("priority").notNull(),
action: varchar("action").$type<"ACCEPT" | "DROP" | "PASS">().notNull(), action: varchar("action").$type<"ACCEPT" | "DROP" | "PASS">().notNull(),
match: varchar("match") match: varchar("match")
.$type<"CIDR" | "PATH" | "IP" | "COUNTRY" | "ASN" | "REGION">() .$type<
| "CIDR"
| "PATH"
| "IP"
| "COUNTRY"
| "COUNTRY_IS_NOT"
| "ASN"
| "REGION"
>()
.notNull(), .notNull(),
value: varchar("value").notNull() value: varchar("value").notNull()
}); });
@@ -1553,3 +1561,4 @@ export type Label = InferSelectModel<typeof labels>;
export type ResourcePolicy = InferSelectModel<typeof resourcePolicies>; export type ResourcePolicy = InferSelectModel<typeof resourcePolicies>;
export type RolePolicy = InferSelectModel<typeof rolePolicies>; export type RolePolicy = InferSelectModel<typeof rolePolicies>;
export type UserPolicy = InferSelectModel<typeof userPolicies>; export type UserPolicy = InferSelectModel<typeof userPolicies>;
export type ResourcePolicyRule = InferSelectModel<typeof resourcePolicyRules>;
+9 -1
View File
@@ -1252,7 +1252,15 @@ export const resourcePolicyRules = sqliteTable("resourcePolicyRules", {
priority: integer("priority").notNull(), priority: integer("priority").notNull(),
action: text("action").$type<"ACCEPT" | "DROP" | "PASS">().notNull(), action: text("action").$type<"ACCEPT" | "DROP" | "PASS">().notNull(),
match: text("match") match: text("match")
.$type<"CIDR" | "PATH" | "IP" | "COUNTRY" | "ASN" | "REGION">() .$type<
| "CIDR"
| "PATH"
| "IP"
| "COUNTRY"
| "COUNTRY_IS_NOT"
| "ASN"
| "REGION"
>()
.notNull(), .notNull(),
value: text("value").notNull() value: text("value").notNull()
}); });
+1 -1
View File
@@ -1321,7 +1321,7 @@ function getRuleAction(input: string) {
function getRuleValue(match: string, value: string) { function getRuleValue(match: string, value: string) {
// if the match is a country, uppercase the value // if the match is a country, uppercase the value
if (match == "COUNTRY") { if (match === "COUNTRY" || match === "COUNTRY_IS_NOT") {
return value.toUpperCase(); return value.toUpperCase();
} }
return value; return value;
+2 -1
View File
@@ -347,12 +347,13 @@ function getRuleAction(input: string): "ACCEPT" | "DROP" | "PASS" {
function getRuleMatch( function getRuleMatch(
input: string input: string
): "CIDR" | "IP" | "PATH" | "COUNTRY" | "ASN" | "REGION" { ): "CIDR" | "IP" | "PATH" | "COUNTRY" | "COUNTRY_IS_NOT" | "ASN" | "REGION" {
return input.toUpperCase() as return input.toUpperCase() as
| "CIDR" | "CIDR"
| "IP" | "IP"
| "PATH" | "PATH"
| "COUNTRY" | "COUNTRY"
| "COUNTRY_IS_NOT"
| "ASN" | "ASN"
| "REGION"; | "REGION";
} }
+2
View File
@@ -74,6 +74,7 @@ export const RESOURCE_RULE_MATCH_TYPES = [
"IP", "IP",
"PATH", "PATH",
"COUNTRY", "COUNTRY",
"COUNTRY_IS_NOT",
"ASN", "ASN",
"REGION" "REGION"
] as const; ] as const;
@@ -96,6 +97,7 @@ export function getResourceRuleValueValidationError(
case "REGION": case "REGION":
return isValidRegionId(value) ? null : "Invalid region ID provided"; return isValidRegionId(value) ? null : "Invalid region ID provided";
case "COUNTRY": case "COUNTRY":
case "COUNTRY_IS_NOT":
return COUNTRIES.some((country) => country.code === value) return COUNTRIES.some((country) => country.code === value)
? null ? null
: "Invalid country code provided"; : "Invalid country code provided";
@@ -229,6 +229,7 @@ export function PolicyAccessRulesTable({
IP: "IP", IP: "IP",
CIDR: t("ipAddressRange"), CIDR: t("ipAddressRange"),
COUNTRY: t("country"), COUNTRY: t("country"),
COUNTRY_IS_NOT: t("countryIsNot"),
ASN: "ASN", ASN: "ASN",
REGION: t("region") REGION: t("region")
}), }),
@@ -441,13 +442,15 @@ export function PolicyAccessRulesTable({
| "IP" | "IP"
| "PATH" | "PATH"
| "COUNTRY" | "COUNTRY"
| "COUNTRY_IS_NOT"
| "ASN" | "ASN"
| "REGION" | "REGION"
) => ) =>
updateRule(row.original.ruleId, { updateRule(row.original.ruleId, {
match: value, match: value,
value: value:
value === "COUNTRY" value === "COUNTRY" ||
value === "COUNTRY_IS_NOT"
? "US" ? "US"
: value === "ASN" : value === "ASN"
? "AS15169" ? "AS15169"
@@ -469,9 +472,14 @@ export function PolicyAccessRulesTable({
{RuleMatch.CIDR} {RuleMatch.CIDR}
</SelectItem> </SelectItem>
{isMaxmindAvailable && ( {isMaxmindAvailable && (
<SelectItem value="COUNTRY"> <>
{RuleMatch.COUNTRY} <SelectItem value="COUNTRY">
</SelectItem> {RuleMatch.COUNTRY}
</SelectItem>
<SelectItem value="COUNTRY_IS_NOT">
{RuleMatch.COUNTRY_IS_NOT}
</SelectItem>
</>
)} )}
{includeRegionMatch && isMaxmindAvailable && ( {includeRegionMatch && isMaxmindAvailable && (
<SelectItem value="REGION"> <SelectItem value="REGION">
@@ -491,7 +499,8 @@ export function PolicyAccessRulesTable({
accessorKey: "value", accessorKey: "value",
header: () => <span className="p-3">{t("value")}</span>, header: () => <span className="p-3">{t("value")}</span>,
cell: ({ row }) => cell: ({ row }) =>
row.original.match === "COUNTRY" ? ( row.original.match === "COUNTRY" ||
row.original.match === "COUNTRY_IS_NOT" ? (
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button <Button
@@ -17,6 +17,7 @@ export const POLICY_RULE_MATCH_TYPES = [
"IP", "IP",
"PATH", "PATH",
"COUNTRY", "COUNTRY",
"COUNTRY_IS_NOT",
"ASN", "ASN",
"REGION" "REGION"
] as const; ] as const;