Browse Source

add rules info card

Milo Schwartz 5 months ago
parent
commit
6e6992e19f
2 changed files with 81 additions and 13 deletions
  1. 1 1
      server/lib/consts.ts
  2. 80 12
      src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx

+ 1 - 1
server/lib/consts.ts

@@ -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);

+ 80 - 12
src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx

@@ -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>
                                     )}
                                 />