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
- All unquoted $i loop counter comparisons and ${TMP_COOKIE} curl
option arguments in the rate limit integration script were flagged
by shellcheck SC2086
- Unquoted variables in [ ] test expressions and curl -b/-c options
can cause subtle failures if the value ever contains whitespace or
glob characters, and are a shellcheck hard warning that blocks CI
linting gates
- Quoted all affected variables in place with no logic changes
- 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
- The rate-limit integration test was sending rate_limit_enable:true in the
security config POST, but the backend injects the Caddy rate_limit handler
only when rate_limit_mode is the string "enabled"
- Because rate_limit_mode was absent from the payload, the database default
of "disabled" persisted and the guard condition always evaluated false,
leaving the handler uninjected across all 10 verify attempts
- Replaced the boolean rate_limit_enable with the string field
rate_limit_mode:"enabled" to match the exact contract the backend enforces
- Added HTTP status checks for login and security config POST requests to ensure proper error handling.
- Implemented a readiness gate for the Caddy admin API before applying security configurations.
- Increased sleep duration before verifying rate limit handler to accommodate Caddy's configuration propagation.
- Changed verification failure from a warning to a hard exit to prevent misleading test results.
- Updated Caddy admin API URL to use the canonical trailing slash in multiple locations.
- Adjusted retry parameters for rate limit verification to reduce polling noise.
- Removed stale GeoIP checksum validation from the Dockerfile's non-CI path to simplify the build process.
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.