- Implement DeleteCertificateDialog component to handle certificate deletion confirmation.
- Add tests for DeleteCertificateDialog covering various scenarios including rendering, confirmation, and cancellation.
- Update translation files for multiple languages to include new strings related to certificate deletion.
- Create end-to-end tests for certificate deletion UX, including button visibility, confirmation dialog, and success/failure scenarios.
When CrowdSec is first enabled, the 10-60 second startup window caused
the toggle to immediately flicker back to unchecked, the card badge to
show 'Disabled' throughout startup, CrowdSecKeyWarning to flash before
bouncer registration completed, and CrowdSecConfig to show alarming
LAPI-not-ready banners to the user.
Root cause: the toggle, badge, and warning conditions all read from
stale sources (crowdsecStatus local state and status.crowdsec.enabled
server data) which neither reflects user intent during a pending mutation.
- Derive crowdsecChecked from crowdsecPowerMutation.variables during
the pending window so the UI reflects intent immediately on click,
not the lagging server state
- Show a 'Starting...' badge in warning variant throughout the startup
window so the user knows the operation is in progress
- Suppress CrowdSecKeyWarning unconditionally while the mutation is
pending, preventing the bouncer key alert from flashing before
registration completes on the backend
- Broadcast the mutation's running state to the QueryClient cache via
a synthetic crowdsec-starting key so CrowdSecConfig.tsx can read it
without prop drilling
- In CrowdSecConfig, suppress the LAPI 'not running' (red) and
'initializing' (yellow) banners while the startup broadcast is active,
with a 90-second safety cap to prevent stale state from persisting
if the tab is closed mid-mutation
- Add security.crowdsec.starting translation key to all five locales
- Add two backend regression tests confirming that empty-string setting
values are accepted (not rejected by binding validation), preventing
silent re-introduction of the Issue 4 bug
- Add nine RTL tests covering toggle stabilization, badge text, warning
suppression, and LAPI banner suppression/expiry
- Add four Playwright E2E tests using route interception to simulate
the startup delay in a real browser context
Fixes Issues 3 and 4 from the fresh-install bug report.
The settings handler SSRF test table expected the generic "private ip"
error string for the cloud-metadata case (169.254.169.254). After the
url_validator was updated to return a distinct "cloud metadata" error for
that address, the handler test's errorContains check failed on every CI run.
Updated the test case expectation from "private" to "cloud metadata" to
match the more precise error message now produced by the validator.
- IPv4-mapped cloud metadata (::ffff:169.254.169.254) previously fell through
the IPv4-mapped IPv6 detection block and returned the generic private-IP error
instead of the cloud-metadata error, making the two cases inconsistent
- The IPv4-mapped error path used ip.String() (the raw ::ffff:… form) directly
rather than sanitizeIPForError, potentially leaking the unsanitized IPv6
address in error messages visible to callers
- Now extracts the IPv4 from the mapped address before both the cloud-metadata
comparison and the sanitization call, so ::ffff:169.254.169.254 produces the
same "access to cloud metadata endpoints is blocked" error as 169.254.169.254
and the error message is always sanitized through the shared helper
- Updated the corresponding test to assert the cloud-metadata message and the
absence of the raw IPv6 representation in the error text
HTTP/HTTPS uptime monitors targeting LAN addresses (192.168.x.x,
10.x.x.x, 172.16.x.x) permanently reported 'down' on fresh installs
because SSRF protection rejects RFC 1918 ranges at two independent
checkpoints: the URL validator (DNS-resolution layer) and the safe
dialer (TCP-connect layer). Fixing only one layer leaves the monitor
broken in practice.
- Add IsRFC1918() predicate to the network package covering only the
three RFC 1918 CIDRs; 169.254.x.x (link-local / cloud metadata)
and loopback are intentionally excluded
- Add WithAllowRFC1918() functional option to both SafeHTTPClient and
ValidationConfig; option defaults to false so existing behaviour is
unchanged for every call site except uptime monitors
- In uptime_service.go, pass WithAllowRFC1918() to both
ValidateExternalURL and NewSafeHTTPClient together; a coordinating
comment documents that both layers must be relaxed as a unit
- 169.254.169.254 and the full 169.254.0.0/16 link-local range remain
unconditionally blocked; the cloud-metadata error path is preserved
- 21 new tests across three packages, including an explicit regression
guard that confirms RFC 1918 blocks are still applied without the
option set (TestValidateExternalURL_RFC1918BlockedByDefault)
Fixes issues 6 and 7 from the fresh-install bug report.
- The DB error return branch in SeedDefaultSecurityConfig was never
exercised because all seed tests only ran against a healthy in-memory
database; added a test that closes the underlying connection before
calling the function so the FirstOrCreate error path is reached
- The letsencrypt certificate cleanup loop in Register was unreachable
in all existing tests because no test pre-seeded a ProxyHost with
an letsencrypt cert association; added a test that creates that
precondition so the log and Update lines inside the loop execute
- These were the last two files blocking patch coverage on PR #852
- The security config Upsert update path copied all rate limit fields
from the incoming request onto the existing database record except
RateLimitMode, so the seeded default value of "disabled" always
survived a POST regardless of what the caller sent
- This silently prevented the Caddy rate_limit handler from being
injected on any container with a pre-existing config record (i.e.,
every real deployment and every CI run after migration)
- Added the missing field assignment so RateLimitMode is correctly
persisted on update alongside all other rate limit settings
- Integration test payload now also sends rate_limit_enable alongside
rate_limit_mode so the handler sync logic fires via its explicit
first branch, providing belt-and-suspenders correctness independent
of which path the caller uses to express intent
On a fresh install the security_configs table is auto-migrated but
contains no rows. Any code path reading SecurityConfig by name received
an empty Go struct with zero values, producing an all-disabled UI state
that offered no guidance to the user and made the security status
endpoint appear broken.
Adds a SeedDefaultSecurityConfig function that uses FirstOrCreate to
guarantee a default row exists with safe, disabled-by-default values on
every startup. The call is idempotent — existing rows are never modified,
so upgrades are unaffected. If the seed fails the application logs a
warning and continues rather than crashing.
Zero-valued rate-limit fields are intentional and safe: the Cerberus
rate-limit middleware applies hardcoded fallback thresholds when the
stored values are zero, so enabling rate limiting without configuring
thresholds results in sensible defaults rather than a divide-by-zero or
traffic block.
Adds three unit tests covering the empty-database, idempotent, and
do-not-overwrite-existing paths.
- Updated the list of supported notification provider types to include 'pushover'.
- Enhanced the notifications API tests to validate Pushover integration.
- Modified the notifications form to include fields specific to Pushover, such as API Token and User Key.
- Implemented CRUD operations for Pushover providers in the settings.
- Added end-to-end tests for Pushover provider functionality, including form rendering, payload validation, and security checks.
- Updated translations to include Pushover-specific labels and placeholders.
The slack sub-tests in TestDiscordOnly_CreateRejectsNonDiscord and
TestBlocker3_CreateProviderRejectsNonDiscordWithSecurityEvents were
omitting the required token field from their request payloads.
CreateProvider enforces that Slack providers must have a non-empty
token (the webhook URL) at creation time. Without it the service
returns "slack webhook URL is required", which the handler does not
classify as a 400 validation error, so it falls through to 500.
Add a token field to each test struct, populate it for the slack
case with a valid-format Slack webhook URL, and use
WithSlackURLValidator to bypass the real format check in unit tests —
matching the pattern used in all existing service-level Slack tests.
- Expanded fetchSessionUser to include Bearer token from localStorage as a fallback for authentication when Secure cookies fail.
- Updated headers to conditionally include Authorization if a token is present.
- Ensured compatibility with the recent fix for the Secure cookie flag on private network connections.
- Updated the notification provider types to include 'slack'.
- Modified API tests to handle 'slack' as a valid provider type.
- Enhanced frontend forms to display Slack-specific fields (webhook URL and channel name).
- Implemented CRUD operations for Slack providers, ensuring proper payload structure.
- Added E2E tests for Slack notification provider, covering form rendering, validation, and security checks.
- Updated translations to include Slack-related text.
- Ensured that sensitive information (like tokens) is not exposed in API responses.