Commit graph

292 commits

Author SHA1 Message Date
6005dbd18a web: add admin scope support to checker API helpers
Make CheckerScope.domainId optional so callers can target the global
admin scope (no domain). getScopedCheckStatus, getScopedCheckOptions,
and updateScopedCheckOptions now short-circuit to the admin /checkers/*
routes when domainId is absent. All narrower-scope callsites gain the
non-null assertion required by the type change.
2026-05-24 18:24:21 +08:00
6ceebe2adb web: disable metrics/json view buttons when data is unavailable
Add a `disableMetrics` store that gets set when metrics fail to load,
preventing users from switching to a broken metrics view. Also disable
the JSON view button when no observations data is present.
2026-05-24 18:23:42 +08:00
680e4dc6e2 web: Improve ui when captcha is required 2026-05-24 17:26:35 +08:00
47049c5b6e web: fix screen freeze after service deletion when zone ID changes
Remove the invalid bind:rr chain between RecordLine and RecordText (RecordText only reads rr, never writes back), and use refreshDomains + invalidateAll instead of directly setting thisZone when the returned zone has a new ID, matching the pattern already used in the domain layout.
2026-05-24 17:26:35 +08:00
2045beb1b1 api-admin: fix reset_password returning empty password when no body sent
Treat io.EOF from ShouldBindJSON as "no body provided" so callers can
POST without a request body to trigger random password generation. Also
fix double-pointer bug (&urp where urp is already *resetPassword) and
bump checker dependencies.
2026-05-24 17:26:31 +08:00
8a7146f4ca web: fix login error showing wrong message and sometimes duplicate toast
When POST /auth returned 401 with an errmsg (e.g. "Invalid username or
password"), customFetch was ignoring it and attempting a session refresh
via GET /auth. The refresh also failed, ultimately throwing
NotAuthorizedError("Not authenticated") instead of the actual credential
error. This also triggered an extra toast in some cases.

Fix by reading errmsg from any 401 response body first: if present, throw
it directly as a plain Error, bypassing the session-refresh logic entirely.
2026-05-24 17:25:34 +08:00
5115ed1993 web: replace Prometheus metrics copy button with explanatory modal
The previous click-to-copy behavior wasn't obvious to users. Show the
URL in a modal with an explicit copy button and a brief scrape_configs
example so users understand what the endpoint is for.
2026-05-24 17:25:34 +08:00
0a120a6d97 web: reset checker state on navigation to avoid stale enabled/options
When switching between checkers via the sidebar, plan.enabled retained
the previous checker's values because the guard condition prevented
re-initialization. Reset all derived state eagerly on checkerId change
and always repopulate plan.enabled from fresh status.
2026-05-24 17:25:34 +08:00
3eca2f3800 web: redesign CheckerScheduleCard with autosave and improved UX
- Move enable/disable toggle to card header (inverted to "Enable scheduling")
- Replace Save button with debounced autosave (700ms) with inline status indicator
- Show interval controls only when enabled; paused hint when disabled
- Remove obsolete no-schedule-yet alert and save button translation keys
2026-05-24 17:25:34 +08:00
31ecf89624 web: mask secret field placeholders when hidden
The HTML placeholder attribute is rendered in plaintext even on
type="password" inputs, so an inherited secret value injected as a
placeholder was visible without toggling the eye button. Replace the
placeholder with bullets of the same length while the secret is hidden, and
reveal the real value only when the user explicitly toggles visibility.
2026-05-24 17:25:34 +08:00
f8c6eb8a88 web: hide rules behind advanced options and show rule descriptions
Rules are now collapsed under the Advanced options toggle instead of
being always visible, and each rule's description is displayed as
helper text below the checkbox when available.
2026-05-24 17:25:34 +08:00
b18c9dc918 web: exclude auto-fill positional from current-scope split
The GetCheckerOptions controller appends a synthetic positional carrying
resolved auto-fill values (consumed by RunCheckModal). splitPositionalOptions
was treating that last entry as the current scope, pushing actual stored
options into inheritedValues — they then showed as placeholders, broke
<select> value matching, and were sent as nil overrides on save. Callers now
pass the auto-fill key set so the synthetic positional is filtered out before
splitting.
2026-05-24 17:25:34 +08:00
3ae7366b00 checker: add plan-level disable toggle to pause scheduling
Adds an explicit Disabled field on CheckPlan so users can pause a
checker's automatic execution without clearing per-rule state. The
scheduler skips Disabled plans alongside fully-disabled ones, and the
schedule card exposes a switch bound through the existing save path.
2026-05-24 17:25:34 +08:00
10c10bc846 web: treat checker All toggle as on when any rule is enabled
Switch the bulk toggle from every-enabled to some-enabled so the
"All" switch reflects an OR across rules: on when at least one is
active, off only when all are disabled.
2026-05-24 17:25:34 +08:00
d8f542a829 web: show distinct toast when toggling checker rules enabled/disabled
Rule toggle switches now call a dedicated handleSavePlan() wrapper with
"rules-updated"/"rules-update-failed" messages, separate from the schedule
card's "Schedule saved" toast. CheckerScheduleCard.save() is split into a
raw export (no toasts) and an internal handleSave() used by its own button.
2026-05-24 17:25:34 +08:00
6983e097ba web: move save toast feedback into checker card/panel components
Each component now owns its success/error toast UX via a handleSave()
wrapper, removing duplicate toast logic from parent saveOptions functions.
2026-05-24 17:25:34 +08:00
3c03bb1306 checker: surface per-rule precheck failures on scoped status
The SDK's new POST /definition returns per-rule precheck errors for the
current options. happyDomain now calls it (or the in-process equivalent
when no remote endpoint is configured) while building each
CheckerStatus, exposes the result as CheckerStatus.PrecheckFailures,
and the rules card in the UI disables the toggle and shows the reason
for any rule whose prerequisites are unmet.
2026-05-24 17:25:34 +08:00
7cfc0ff7e0 web: Display rules page when no observations exists 2026-05-24 17:25:34 +08:00
0d0e220c06 web: use ClassValue from svelte/elements for class props
Replace class?: string with class?: ClassValue across Svelte components,
adopting the idiomatic Svelte 5 array syntax (class={["base", className]})
instead of string interpolation for combining static and dynamic classes.
2026-05-24 17:25:34 +08:00
98ceb57175 web: Improve sidebar in domain/services/checks 2026-05-24 17:25:34 +08:00
7cb67c452f web: Fix sidebar button hell 2026-05-24 17:25:34 +08:00
056ceb1778 checkers: poll execution status while running instead of fetching empty data
When opening an execution detail page while the execution is still
pending or running, defer fetching observations/results/metrics and
poll the execution status every 3s until it reaches a terminal state.
The loading view shows a "Running" label in the meantime.
2026-05-24 17:25:34 +08:00
ff6dbc1f7a checkers: prefer HTML report over metrics as default view
HTML reports typically provide a richer summary than raw metrics, so
when both are available we open the HTML tab first.
2026-05-24 17:25:34 +08:00
20de284c25 checkers: default to rules view when execution failed
Surfaces error details immediately instead of opening metrics or HTML
report tabs that may be empty or misleading for failed runs.
2026-05-24 17:25:34 +08:00
075448ef67 web: silence isAuthUser errors on settings page for OIDC users 2026-05-24 17:25:34 +08:00
ed80de9e71 web: Prioritize HTML report view over metrics as default 2026-05-24 17:25:34 +08:00
6cf60bf17f web: sort checker list alphabetically in sidebar 2026-05-24 17:25:34 +08:00
b94bc83e58 chore(deps): update dependency typescript to v6
All checks were successful
continuous-integration/drone/push Build is passing
2026-05-10 14:11:03 +00:00
f0b3a0f94d ci: fix pipeline inconsistencies and improve Docker builds
- Replace DRONE_TAG##v with DRONE_SEMVER across all pipelines
- Add missing VERSION build_args and tag-specific Docker publish steps to amd64 pipeline
- Add prerelease: true to amd64 release publish steps for consistency with arm64
- Pin swag and go-licenses versions with renovate annotations
- Add renovate regex manager to track go install versions in .drone.yml
- Add BuildKit cache mounts and OCI labels to Dockerfiles
- Improve Dockerfile layer efficiency (separate web/web-admin asset copies, smaller COPY targets)
- Move npm build/generate directives to separate generate_npm.go files with //go:build ignore
- Update README build instructions to include web-admin and correct step order
2026-05-10 20:17:55 +08:00
a037e39df2 Fix malformed manifest.json 2026-05-10 20:17:55 +08:00
a32544cbae web: add notification settings UI under /me/notifications 2026-04-30 14:05:01 +00:00
3d0d6db33f web: add Email Auto-configuration service editor and translations
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-29 18:51:51 +07:00
4a8ac74ffb web: pre-select rules in RunCheckModal from existing plan
Some checks are pending
continuous-integration/drone/push Build is running
2026-04-29 18:51:51 +07:00
0a635ee9f5 web: Sort checker list by alphabetical order
Some checks are pending
continuous-integration/drone/push Build is running
2026-04-29 17:20:16 +07:00
ccb79b081d web: Add editor for svcs.DMARCReport service
All checks were successful
continuous-integration/drone/push Build is passing
Provides a minimal table UI to manage the list of reporting domains
authorised via <reportingdomain>._report._dmarc TXT records, replacing
the Orphan editor fallback.
2026-04-29 14:20:59 +07:00
8e36050683 web: Improve error handling when servicesSpecs is not up-to-date 2026-04-29 13:47:27 +07:00
3df5a47238 Add CAA checker, based on TLS observations 2026-04-28 11:56:51 +00:00
d000366434 Handling Kerberos records (analyzer + editor + checker) 2026-04-28 18:20:10 +07:00
0dceb15a76 Handling SIP records (analyzer + editor + checker) 2026-04-28 18:19:35 +07:00
6260aaa74d Add XMPP checks + handle xmpps 2026-04-28 18:19:35 +07:00
f37eb45159 Handling CalDAV and CardDAV records (analyzers + editors + checker) 2026-04-28 18:19:35 +07:00
4ac00009f8 web: revamp TLSA editor. Able to import certificate and fetch through API current chain to auto-fill 2026-04-28 18:03:55 +07:00
6737e33fcb bimi: support BIMI declination records
All checks were successful
continuous-integration/drone/push Build is passing
The BIMI draft lets a domain explicitly opt out of BIMI by publishing
a record with v=BIMI1 and an empty l= tag. Surface that in the editor
and treat it as a first-class case in compliance.
2026-04-28 17:59:38 +07:00
04e072a257 compliance: BIMI record sync validators
Validators run synchronously and surface:

- Owner-name shape: <selector>._bimi (rejects empty selectors and
  non-label characters).
- Version: only "BIMI1" is accepted by the current draft.
- Logo URL: l= is mandatory, must be HTTPS, warns when the path does
  not end in .svg.
- VMC URL: optional but flagged as info when missing (Gmail and Yahoo
  need it). Must be HTTPS when present; info if it does not look like
  a .pem file.
- Evidence URL: must be HTTPS when present.
- Cross-record DMARC check: warns when no DMARC is published or when
  every DMARC at the apex sits at p=none, since BIMI is only honoured
  with an enforcing DMARC policy.
2026-04-28 17:59:32 +07:00
8fcd40b9b7 web: BIMI editor and parser/serializer
Adds the frontend pieces needed to edit a BIMI record from the zone UI.
2026-04-28 17:59:19 +07:00
edbba509bf services: add BIMI service backend
Adds support for Brand Indicators for Message Identification (BIMI),
the emerging standard that lets receiving mail clients display verified
brand logos next to authenticated messages.
2026-04-28 17:58:48 +07:00
c91c2ca35f compliance: DMARC cross-domain report authorization
Surfaces the RFC 7489 sec. 7.1 trap: when a DMARC record at example.com
publishes rua/ruf addresses on a third-party domain, that domain must
publish "v=DMARC1" at example.com._report._dmarc.<external> to authorize
report delivery. Without it, reports are silently dropped, which is by
far the most common cause of "DMARC is published but no report ever
arrives".
2026-04-28 17:58:33 +07:00
1386a1056a compliance: MTA-STS cross-check policy mx vs zone MX
Adds zone-aware checks to the MTA-STS async validator. Once the policy
file is fetched and parsed, compare its mx patterns to the apex MX
records of the current zone (RFC 8461 sec. 4.1):

- mta_sts.zone-no-mx (warning): the policy lists mx entries but the
  zone has no MX records, so receivers will refuse delivery.
- mta_sts.zone-mx-not-covered (error in enforce, warning in testing):
  one of the apex MX hosts is not matched by any policy pattern.
  Senders enforcing the policy will reject mail to that host.
- mta_sts.policy-mx-unused (info): a policy pattern matches no MX in
  the zone, hinting at a stale entry.
2026-04-28 17:57:26 +07:00
a9cb3c6422 compliance: MX record sync validators
Validates a MX record set (svcs.MXs) at edit time:

- Null MX (RFC 7505): a "." target must be the only MX in the set, with
  preference 0. Both deviations are surfaced.
- Targets: invalid hostnames, out-of-range preferences (uint16) and
  duplicate targets (case-insensitive on the FQDN).
- Cross-zone: flags MX targets that are CNAME owners in the same zone
  (RFC 5321 sec. 5.1) and warns when an in-zone target lacks any
  A/AAAA service. External targets are left to runtime checkers.
2026-04-28 17:57:26 +07:00
c32efe0cf7 compliance: DMARC cross-checks against zone DKIM and SPF
Extends the compliance context with findAllServices(type?) so a
validator can iterate every service in the zone, not just a single
subdomain. The DMARC validator now uses it to flag configurations
where alignment is structurally impossible:

- p=quarantine|reject and the zone has neither a DKIM nor an SPF
  record -> error: every legitimate message will fail DMARC.
- p=none in the same situation -> warning: DMARC has nothing to
  align against, monitoring data will be empty.
- adkim=s (strict DKIM alignment) with no DKIM record published
  anywhere in the zone -> warning: only SPF alignment can succeed.
2026-04-28 17:57:26 +07:00