Conversation
Adds a per-location firewall editor under /waf: a location selector that loads that zone's ruleset via waf.get, a description field, and an editable rules table (id, description, CEL expression, action, priority, plus HTTP status + message inputs shown only when the action is block). Saves the whole ruleset with waf.set and disables the firewall via waf.delete behind a confirm in a danger zone. Includes the Firewall sidebar entry, Api.WafZone / Api.WafRule types, and mock fixtures for offline dev. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Deploying deploys-app--console with
|
| Latest commit: |
161293f
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://8d6a6b8c.deploys-app--console.pages.dev |
| Branch Preview URL: | https://feat-waf.deploys-app--console.pages.dev |
Add a "Build…" helper next to each rule's expression that opens an in-page modal to compose one condition from form controls (field, operator, value, case-insensitive/url-decode/negate), shows a live CEL preview, and inserts the generated snippet into the raw expression — combining with AND/OR or replacing when the rule already has an expression. CEL is generated only from parapet's portable helper functions (containsAny, hasPrefixAny, regexMatch, ipInCidr, lower, urlDecode) rather than the non-portable .startsWith/.contains/.matches string methods. The generation lives in a pure, testable module (src/lib/waf/expression.js). The raw expression field stays the source of truth and is now a monospace textarea. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The expression is now a readonly field set exclusively via the Build… wizard (plus a Clear action), so rules can only be composed from the portable CEL helpers. Rule ids are auto-generated and stable across reorders, shown read-only. Replace the manual priority input with move up/down controls — row order is the execution order (priority is derived from position on save). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the detail-heavy firewall table with a compact summary list (ID, Description, Action + row actions) and edit each rule in a working-copy modal that embeds the CEL condition builder. Retires the standalone WafExpressionModal in favor of the in-modal builder. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the WAF rule modal with a list + detail page flow. The list page reflects server state for the selected location and persists move/remove optimistically (reloading on error), with an explicit Save for the zone description; the new edit page hosts the rule fields and condition builder and writes the whole zone on Save. The location is carried in the URL so context survives navigating to the edit page and back. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ression mode Reorder the edit page to read top-to-bottom like Cloudflare's custom-rule editor: Description, then "When incoming requests match" (the expression), then "Then take action" (Action + block-only response fields) above Save. Add a Visual/Expression toggle over the same expression string — Visual keeps the condition builder, Expression exposes an editable monospace CEL textarea so raw rules can be typed or pasted. Switching modes preserves the expression, and a shared Clear stays available in both. The builder gains a `showPreview` prop (and exposes `clearExpression`) so the page can render its own raw editor. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Split the single WAF management page into an index that lists configured firewalls, a create page that picks an unconfigured location, and a manage page where the location is read-only. The index and create pages fan out waf.get per location (no list-zones endpoint exists) to discover which locations are configured. The mock now returns the seed zone only for gke.cluster-rcf2 and not-found elsewhere, and remembers locations created in-session so the create -> manage flow is coherent. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ion builder Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drive the WAF condition builder's value input from the selected field and operator: a TLS on/off toggle for the scheme field (https/http), a free-text datalist combobox for method equals/not_equals, and a chip-based TagInput for the contains-any/starts-with-any operators. Drop the Body field. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add an optional `editable` mode to Select.svelte so a free-text combobox renders with the same trigger/chevron/menu styling as the standard dropdown. When `editable` is false the component behaves exactly as before, so all existing usages are untouched. Use it for the WAF Method value control, replacing the native `<input list>` + `<datalist>` that looked inconsistent with the other dropdowns while still allowing custom methods (e.g. PURGE). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add parseExpression() as the conservative inverse of the CEL generator so the visual builder can reflect an existing expression. Rebuild WafConditionBuilder as a two-way-bound, rows-based editor (one row per condition + AND/OR combinator) and gate the Visual tab on the expression being representable — complex expressions (mixed &&/||, grouping, unknown functions, .startsWith, malformed) keep the editor in raw mode with a hint. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a small "Preview" badge next to the Firewall nav item to signal the feature is still in preview. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/waf, modeled on the existing location-scopedroute/pull-secretpages.Selectlocation picker at the top loads that location's ruleset viawaf.get; a missing zone is treated as the normal "not configured yet" state (empty editor, not an error screen).id,description,expression(wide CEL input),action(log/allow/blockviaSelect),priority(number), and HTTPstatus+messageinputs that appear only whenaction === 'block'(defaults 403 / "Forbidden"). Add-row and remove-row buttons use Svelte 5$statearrays.waf.set; Disable firewall (in aDangerZone, behind a confirm modal) callswaf.delete. Errors surface through the standardmodal.errorhandler.Firewallentry to the project sidebar (shield icon, between Routes and Workload Identities),Api.WafZone/Api.WafRuletypes, andwaf.get/waf.set/waf.deletemock fixtures for offline dev.Notes
status/messageare sent as flat rule fields (and only when blocking), matching the API contract; ruleprioritydefaults to 0.npm run lint,npm run check, andnpm run buildall pass with zero errors/warnings.Test plan
npm run lint— cleannpm run check(svelte-check) — 0 errors / 0 warningsnpm run build— succeedsnpm run dev:mock+ Playwright: page renders in light and dark mode, location selector loads the zone, Add Rule appends a row, switching a row's action to "Block" reveals the status/message inputs, no console/page errors.waf.*endpoints are deployed.🤖 Generated with Claude Code