add rules info card

This commit is contained in:
Milo Schwartz 2025-02-09 23:23:55 -05:00
parent 34e3fe690d
commit 6e6992e19f
No known key found for this signature in database
2 changed files with 81 additions and 13 deletions

View file

@ -2,7 +2,7 @@ import path from "path";
import { fileURLToPath } from "url";
// This is a placeholder value replaced by the build process
export const APP_VERSION = "1.0.0-beta.12";
export const APP_VERSION = "1.0.0-beta.13";
export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME);

View file

@ -57,6 +57,15 @@ import {
} from "@app/components/Settings";
import { ListResourceRulesResponse } from "@server/routers/resource/listResourceRules";
import { SwitchInput } from "@app/components/SwitchInput";
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { Check, Info, InfoIcon, X } from "lucide-react";
import {
InfoSection,
InfoSections,
InfoSectionTitle
} from "@app/components/InfoSection";
import { Separator } from "@app/components/ui/separator";
import { InfoPopup } from "@app/components/ui/info-popup";
// Schema for rule validation
const addRuleSchema = z.object({
@ -70,6 +79,11 @@ type LocalRule = ArrayElement<ListResourceRulesResponse["rules"]> & {
updated?: boolean;
};
enum RuleAction {
ACCEPT = "Always Allow",
DROP = "Always Deny"
}
export default function ResourceRules(props: {
params: Promise<{ resourceId: number }>;
}) {
@ -296,8 +310,10 @@ export default function ResourceRules(props: {
{row.original.action}
</SelectTrigger>
<SelectContent>
<SelectItem value="ACCEPT">ACCEPT</SelectItem>
<SelectItem value="DROP">DROP</SelectItem>
<SelectItem value="ACCEPT">
{RuleAction.ACCEPT}
</SelectItem>
<SelectItem value="DROP">{RuleAction.DROP}</SelectItem>
</SelectContent>
</Select>
)
@ -367,6 +383,56 @@ export default function ResourceRules(props: {
return (
<SettingsContainer>
<Alert>
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">About Rules</AlertTitle>
<AlertDescription className="mt-4">
<p className="mb-4">
Rules allow you to control access to your resource based
on a set of criteria. You can create rules to allow or
deny access based on IP address or URL path. Deny rules
take precedence over allow rules. If a request matches
both an allow and a deny rule, the deny rule will be
applied.
</p>
<InfoSections>
<InfoSection>
<InfoSectionTitle>Actions</InfoSectionTitle>
<ul className="text-sm text-muted-foreground space-y-1">
<li className="flex items-center gap-2">
<Check className="text-green-500 w-4 h-4" />
Always Allow: Bypass all authentication
methods
</li>
<li className="flex items-center gap-2">
<X className="text-red-500 w-4 h-4" />
Always Deny: Block all requests; no
authentication can be attempted
</li>
</ul>
</InfoSection>
<Separator orientation="vertical" />
<InfoSection>
<InfoSectionTitle>
Matching Criteria
</InfoSectionTitle>
<ul className="text-sm text-muted-foreground space-y-1">
<li className="flex items-center gap-2">
Match a specific IP address
</li>
<li className="flex items-center gap-2">
Match a range of IP addresses in CIDR
notation
</li>
<li className="flex items-center gap-2">
Match a URL path or pattern
</li>
</ul>
</InfoSection>
</InfoSections>
</AlertDescription>
</Alert>
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>Enable Rules</SettingsSectionTitle>
@ -420,10 +486,10 @@ export default function ResourceRules(props: {
</SelectTrigger>
<SelectContent>
<SelectItem value="ACCEPT">
ACCEPT
{RuleAction.ACCEPT}
</SelectItem>
<SelectItem value="DROP">
DROP
{RuleAction.DROP}
</SelectItem>
</SelectContent>
</Select>
@ -469,18 +535,20 @@ export default function ResourceRules(props: {
name="value"
render={({ field }) => (
<FormItem>
<FormLabel>Value</FormLabel>
<InfoPopup
text="Value"
info={
addRuleForm.watch(
"match"
) === "CIDR"
? "Enter an address in CIDR format (e.g., 103.21.244.0/22)"
: "Enter a URL path or pattern (e.g., /api/v1/todos or /api/v1/*)"
}
/>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
<FormDescription>
Enter CIDR{" "}
{resource.http
? "or path value"
: ""}{" "}
based on match type
</FormDescription>
</FormItem>
)}
/>