From 2428738fa6ea36823fcdd8afe17b29f4c0029117 Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 9 Feb 2025 21:47:59 -0500 Subject: [PATCH 1/4] Fix missing ruleId issue --- .../[resourceId]/connectivity/page.tsx | 4 ++-- .../resources/[resourceId]/rules/page.tsx | 24 ++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx index 0e85319..b3b26a5 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 ac863c5..b5038b3 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/rules/page.tsx @@ -243,30 +243,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({ From 5e92aebd20ff3bed818a8c9f95493e4c4c8221e1 Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 9 Feb 2025 21:56:39 -0500 Subject: [PATCH 2/4] Drop first --- server/routers/badger/verifySession.ts | 40 ++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index 4515e98..ce8d321 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 && + (clientIp && rule.match == "CIDR" && - isIpInCidr(clientIp, rule.value) + 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"; } } } From bbc1a9eac40a1d5d4755d9cbd4d8adc594007ab5 Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 9 Feb 2025 22:00:02 -0500 Subject: [PATCH 3/4] Format --- server/routers/badger/verifySession.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index ce8d321..a3c6abb 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -491,13 +491,13 @@ async function checkRules( for (const rule of rules) { if ( (clientIp && - rule.match == "CIDR" && - isIpInCidr(clientIp, rule.value) && - rule.action === "DROP") || + rule.match == "CIDR" && + isIpInCidr(clientIp, rule.value) && + rule.action === "DROP") || (path && - rule.match == "PATH" && - urlGlobToRegex(rule.value).test(path) && - rule.action === "DROP") + rule.match == "PATH" && + urlGlobToRegex(rule.value).test(path) && + rule.action === "DROP") ) { return "DROP"; } @@ -511,14 +511,14 @@ async function checkRules( if (hasAcceptRule) { for (const rule of rules) { if (rule.action !== "ACCEPT") continue; - + if ( (clientIp && - rule.match == "CIDR" && - isIpInCidr(clientIp, rule.value)) || + rule.match == "CIDR" && + isIpInCidr(clientIp, rule.value)) || (path && - rule.match == "PATH" && - urlGlobToRegex(rule.value).test(path)) + rule.match == "PATH" && + urlGlobToRegex(rule.value).test(path)) ) { return "ACCEPT"; } From 4bce210ff560f08e9358603520471b3658676fa0 Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 9 Feb 2025 22:03:18 -0500 Subject: [PATCH 4/4] Be more lenient with leading and trailing slashes --- server/routers/badger/verifySession.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index a3c6abb..a65b24a 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -529,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, "\\$&"); @@ -540,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