|
@@ -101,7 +101,7 @@ export default function ResourceRules(props: {
|
|
resolver: zodResolver(addRuleSchema),
|
|
resolver: zodResolver(addRuleSchema),
|
|
defaultValues: {
|
|
defaultValues: {
|
|
action: "ACCEPT",
|
|
action: "ACCEPT",
|
|
- match: "CIDR",
|
|
|
|
|
|
+ match: "IP",
|
|
value: ""
|
|
value: ""
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -167,6 +167,15 @@ export default function ResourceRules(props: {
|
|
setLoading(false);
|
|
setLoading(false);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ if (data.match === "IP" && !isValidIP(data.value)) {
|
|
|
|
+ toast({
|
|
|
|
+ variant: "destructive",
|
|
|
|
+ title: "Invalid IP",
|
|
|
|
+ description: "Please enter a valid IP address"
|
|
|
|
+ });
|
|
|
|
+ setLoading(false);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
const newRule: LocalRule = {
|
|
const newRule: LocalRule = {
|
|
...data,
|
|
...data,
|
|
@@ -255,6 +264,15 @@ export default function ResourceRules(props: {
|
|
setLoading(false);
|
|
setLoading(false);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ if (rule.match === "IP" && !isValidIP(rule.value)) {
|
|
|
|
+ toast({
|
|
|
|
+ variant: "destructive",
|
|
|
|
+ title: "Invalid IP",
|
|
|
|
+ description: "Please enter a valid IP address"
|
|
|
|
+ });
|
|
|
|
+ setLoading(false);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
if (rule.new) {
|
|
if (rule.new) {
|
|
const res = await api.put(`/resource/${params.resourceId}/rule`, data);
|
|
const res = await api.put(`/resource/${params.resourceId}/rule`, data);
|
|
@@ -336,7 +354,7 @@ export default function ResourceRules(props: {
|
|
cell: ({ row }) => (
|
|
cell: ({ row }) => (
|
|
<Select
|
|
<Select
|
|
defaultValue={row.original.match}
|
|
defaultValue={row.original.match}
|
|
- onValueChange={(value: "CIDR" | "PATH") =>
|
|
|
|
|
|
+ onValueChange={(value: "CIDR" | "IP" | "PATH") =>
|
|
updateRule(row.original.ruleId, { match: value })
|
|
updateRule(row.original.ruleId, { match: value })
|
|
}
|
|
}
|
|
>
|
|
>
|
|
@@ -344,7 +362,8 @@ export default function ResourceRules(props: {
|
|
{row.original.match}
|
|
{row.original.match}
|
|
</SelectTrigger>
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectContent>
|
|
- <SelectItem value="CIDR">CIDR</SelectItem>
|
|
|
|
|
|
+ <SelectItem value="IP">IP</SelectItem>
|
|
|
|
+ <SelectItem value="CIDR">IP Range</SelectItem>
|
|
<SelectItem value="PATH">PATH</SelectItem>
|
|
<SelectItem value="PATH">PATH</SelectItem>
|
|
</SelectContent>
|
|
</SelectContent>
|
|
</Select>
|
|
</Select>
|
|
@@ -527,8 +546,11 @@ export default function ResourceRules(props: {
|
|
<SelectValue />
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectContent>
|
|
|
|
+ <SelectItem value="IP">
|
|
|
|
+ IP
|
|
|
|
+ </SelectItem>
|
|
<SelectItem value="CIDR">
|
|
<SelectItem value="CIDR">
|
|
- CIDR
|
|
|
|
|
|
+ IP Range
|
|
</SelectItem>
|
|
</SelectItem>
|
|
{resource.http && (
|
|
{resource.http && (
|
|
<SelectItem value="PATH">
|
|
<SelectItem value="PATH">
|
|
@@ -657,6 +679,21 @@ function isValidCIDR(cidr: string): boolean {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+function isValidIP(ip: string): boolean {
|
|
|
|
+ const ipPattern = /^([0-9]{1,3}\.){3}[0-9]{1,3}$/;
|
|
|
|
+
|
|
|
|
+ if (!ipPattern.test(ip)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const octets = ip.split(".");
|
|
|
|
+
|
|
|
|
+ return octets.every((octet) => {
|
|
|
|
+ const num = parseInt(octet, 10);
|
|
|
|
+ return num >= 0 && num <= 255;
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
function isValidUrlGlobPattern(pattern: string): boolean {
|
|
function isValidUrlGlobPattern(pattern: string): boolean {
|
|
// Remove leading slash if present
|
|
// Remove leading slash if present
|
|
pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;
|
|
pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;
|