diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index 4515e981..a65b24a0 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -485,18 +485,42 @@ async function checkRules( return; } + let hasAcceptRule = false; + + // First pass: look for DROP rules for (const rule of rules) { if ( - clientIp && - rule.match == "CIDR" && - isIpInCidr(clientIp, rule.value) + (clientIp && + rule.match == "CIDR" && + isIpInCidr(clientIp, rule.value) && + rule.action === "DROP") || + (path && + rule.match == "PATH" && + urlGlobToRegex(rule.value).test(path) && + rule.action === "DROP") ) { - return rule.action as "ACCEPT" | "DROP"; - } else if (path && rule.match == "PATH") { - // rule.value is a regex, match on the path and see if it matches - const re = urlGlobToRegex(rule.value); - if (re.test(path)) { - return rule.action as "ACCEPT" | "DROP"; + return "DROP"; + } + // Track if we see any ACCEPT rules for the second pass + if (rule.action === "ACCEPT") { + hasAcceptRule = true; + } + } + + // Second pass: only check ACCEPT rules if we found one and didn't find a DROP + if (hasAcceptRule) { + for (const rule of rules) { + if (rule.action !== "ACCEPT") continue; + + if ( + (clientIp && + rule.match == "CIDR" && + isIpInCidr(clientIp, rule.value)) || + (path && + rule.match == "PATH" && + urlGlobToRegex(rule.value).test(path)) + ) { + return "ACCEPT"; } } } @@ -505,8 +529,8 @@ async function checkRules( } function urlGlobToRegex(pattern: string): RegExp { - // Remove leading slash if present (we'll add it to the regex pattern) - pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern; + // Trim any leading or trailing slashes + pattern = pattern.replace(/^\/+|\/+$/g, ""); // Escape special regex characters except * const escapedPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&"); @@ -516,6 +540,7 @@ function urlGlobToRegex(pattern: string): RegExp { // Create the final pattern that: // 1. Optionally matches leading slash - // 2. Matches the entire string - return new RegExp(`^/?${regexPattern}$`); -} + // 2. Matches the pattern + // 3. Optionally matches trailing slash + return new RegExp(`^/?${regexPattern}/?$`); +} \ No newline at end of file diff --git a/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx index 0e853194..b3b26a5a 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx @@ -269,7 +269,7 @@ export default function ReverseProxyTargets(props: { >(`/resource/${params.resourceId}/target`, data); target.targetId = res.data.data.targetId; } else if (target.updated) { - const res = await api.post( + await api.post( `/target/${target.targetId}`, data ); @@ -290,7 +290,7 @@ export default function ReverseProxyTargets(props: { for (const targetId of targetsToRemove) { await api.delete(`/target/${targetId}`); setTargets( - targets.filter((target) => target.targetId !== targetId) + targets.filter((t) => t.targetId !== targetId) ); } diff --git a/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx index 287e767a..bffcc9ae 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx @@ -257,30 +257,42 @@ export default function ResourceRules(props: { } if (rule.new) { - await api.put(`/resource/${params.resourceId}/rule`, data); + const res = await api.put(`/resource/${params.resourceId}/rule`, data); + rule.ruleId = res.data.data.ruleId; } else if (rule.updated) { await api.post( `/resource/${params.resourceId}/rule/${rule.ruleId}`, data ); } + + setRules([ + ...rules.map((r) => { + let res = { + ...r, + new: false, + updated: false + }; + return res; + }) + ]); } for (const ruleId of rulesToRemove) { await api.delete( `/resource/${params.resourceId}/rule/${ruleId}` ); + setRules( + rules.filter((r) => r.ruleId !== ruleId) + ); } - setRules( - rules.map((rule) => ({ ...rule, new: false, updated: false })) - ); - setRulesToRemove([]); - toast({ title: "Rules updated", description: "Rules updated successfully" }); + + setRulesToRemove([]); } catch (err) { console.error(err); toast({