Commit graph

292 commits

Author SHA1 Message Date
4dbc59725a compliance: MTA-STS async policy fetch
Wires the new POST /api/resolver/mta-sts-policy endpoint into the
MTA-STS validator. The async pass runs after the local TXT checks,
debounced and cancellable through EditorCompliance, and surfaces:

- Transport-level failures: dns-error, tls-error, fetch-error,
  too-large.
- HTTP-level failures: not-found (404), http-error (other non-2xx),
  redirect (server tried to redirect, RFC 8461 sec. 3.3 forbids it).
- Policy file content: missing/invalid version, missing/invalid mode,
  mode=none (warning, effectively disabled), mode=testing (info),
  missing mx in enforce/testing modes, missing/out-of-range max_age
  (0..31557600), short max_age (< 1 day, warning).
2026-04-28 17:57:26 +07:00
577e8557a3 compliance: TLS-RPT record sync validators
Adds checks for svcs.TLS_RPT against RFC 8460 sec. 3.

The validator surfaces:

- Wrong owner name (must be _smtp._tls.<domain>).
- Missing or non-TLSRPTv1 v= tag.
- Missing rua= report destination.
- Empty entries inside rua=.
- rua URIs that are neither mailto: nor http(s):.
- Malformed mailto URIs (missing @ or domain).
2026-04-28 17:57:26 +07:00
b27b2745d6 compliance: MTA-STS record sync validators
Adds checks for svcs.MTA_STS against RFC 8461 sec. 3.1.

The validator surfaces:

- Wrong owner name (must be _mta-sts.<domain>).
- Missing or non-STSv1 v= tag.
- Missing id= tag.
- id= containing characters outside [A-Za-z0-9] or longer than 32 chars.
2026-04-28 17:57:26 +07:00
99dace151e compliance: DMARC record validators
Adds compliance checks for svcs.DMARC against RFC 7489.

The validator parses the published TXT and surfaces:

- Wrong owner name (record must live at _dmarc.<domain>).
- Missing or non-DMARC1 v= tag.
- Missing, unknown, or "monitoring-only" p= policy.
- Invalid sp= subdomain policy.
- Invalid adkim/aspf alignment values.
- pct= out of [0..100] (error) and pct < 100 (info, partial deployment).
- Non-positive or non-numeric ri=.
- Unknown fo= entries (0 / 1 / d / s) and unknown rf= formats (afrf).
- Empty or malformed rua/ruf URIs (mailto and http(s) accepted; mailto
  size suffix !N preserved).
2026-04-28 17:57:26 +07:00
e2bf286a56 compliance: SPF async recursive flatten
Wires the new POST /api/resolver/spf-flatten endpoint into the SPF
validator. The async path runs after the local checks, debounced and
cancellable through EditorCompliance, and surfaces:

- spf.recursive-many-lookups / spf.recursive-too-many-lookups based on
  the recursive lookupCount returned by the backend
- spf.too-many-void-lookups when more than 2 NXDOMAIN/NoData responses
  occur during the walk (RFC 7208 §4.6.4)
- per-include diagnostics: spf.include-loop, spf.include-no-spf,
  spf.include-resolver-error, spf.include-error — pointing at the exact
  domain and mechanism that failed
2026-04-28 17:57:26 +07:00
5f8862c384 resolver: POST /api/resolver/spf-flatten endpoint
Adds a recursive SPF flatten endpoint sized for the compliance UI:

- happydns.SPFFlattenRequest accepts a {domain, record?} pair so the UI
  can preview an unsaved record without persisting it first; the optional
  inline record bypasses the root TXT lookup.
- happydns.SPFFlattenResponse returns the recursive tree with per-node
  Mechanism / Domain / Record / LookupsHere / Error fields, plus the
  RFC 7208 §4.6.4 budget counters (LookupCount, VoidLookups, Exceeded,
  VoidExceeded, Truncated).
- Hard caps at 10 lookups, 2 void lookups, depth 12, 2s per query and
  10s overall. Cycle detection via the visited-domain set.
- Resolver selection mirrors ResolveQuestion (local / custom / default
  to 1.1.1.1) with the same IPv6-bracket handling.
2026-04-28 17:57:08 +07:00
48530dd212 compliance: SPF local validators
Extracts the SPF parser/serializer out of the editor into
$lib/services/spf.ts (matching dmarc.ts / mta_sts.ts) and adds a sync
validator that flags non-recursive issues against RFC 7208:

- missing or wrong v=spf1
- absence / multiplicity / non-final placement of ‘all’
- redirect= combined with ‘all’ or duplicated
- ptr deprecation (RFC 7208 §5.5)
- local DNS-lookup budget (warn ≥8, error >10) — recursive flatten will
  come later via an async backend endpoint
- mechanisms missing values, empty terms, duplicates, length cap
2026-04-28 17:55:40 +07:00
faf21f63b1 compliance: DKIM record sync validators
Validates a DKIM TXT record (svcs.DKIMRecord) at edit time:

- Selector: must be present, must match the label charset.
- Version: only "DKIM1" is accepted (RFC 6376 sec. 3.6.1).
- Public key: detects missing p=, empty p= (revocation, warning), and
  non-base64 payloads. Warns on RSA keys shorter than ~2048 bits and
  errors on RSA keys shorter than ~1024 bits per RFC 8301.
- Algorithms: warns on SHA-1 (RFC 8301) and unknown hashes; flags
  unknown key types or service types.
- Flags: surfaces t=y (testing) as info; warns on unknown flags.
- Granularity: marks g= as deprecated since RFC 6376.
2026-04-28 17:55:40 +07:00
893597688e compliance: add records-compliance infra (types, registry, editor panel)
Introduces the frontend-only compliance framework that lets each editor
contribute spec-conformance checks.

No validators are registered yet.
2026-04-28 17:55:40 +07:00
7251d93619 web: simplify service editors with single-source-of-truth state
Replace dueling parse/stringify $effects across service editors with
one-time top-level init plus a single write-back $effect. Remount
editors via {#key value} in ServiceEditor so children no longer need
inbound-sync logic.
2026-04-28 17:55:40 +07:00
392e7fb344 checkers: thread rule States into ReportContext for reports
Propagate the persisted CheckEvaluation.States through BuildReportContext
and the HTTP report transport so reporters can render rule-driven
sections (hints, severity) without re-deriving them from raw data. When
no evaluation is available the context carries nil states, matching the
SDK's documented nil-safe fallback to data-only rendering.
2026-04-28 13:06:23 +07:00
fa781a537d checkers: migrate to checker-sdk-go v1.2.0 []CheckState signature
Rules now return []CheckState, the engine stamps RuleName from the rule,
and the HTTP rule-result lookup matches on RuleName rather than Code.
domain_contact emits one state per role (Subject) instead of a
concatenated single-state message.
2026-04-28 13:06:23 +07:00
0bee7695bc web: sort sessions by last used date in SessionsManager
All checks were successful
continuous-integration/drone/push Build is passing
Fixes: https://feedback.happydomain.org/posts/23/current-connection-sorted-list
2026-04-17 18:04:04 +07:00
a4f3595142 Use nodeJS workspace
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-17 12:58:17 +07:00
57de739f80 web: add Prometheus metrics URL link to checker config page 2026-04-16 17:08:05 +07:00
e857b1fb99 web-admin: wire dashboard to /metrics with collapsible details
Replaces the three REST count calls with a single Prometheus scrape that
auto-refreshes every 15s, surfaces queue/worker/in-flight/RSS/version/uptime
as featured cards, and tucks counters and Go runtime stats under a
"Show more metrics" Collapse.
2026-04-16 17:08:05 +07:00
8a546a8b41 domaininfo: add RDAP/WHOIS lookup feature
Introduces a domaininfo package with RDAP and WHOIS getters, exposed
through a new DomainInfoUsecase and /api/domaininfo/:domain route (also
mounted under domain scope). Adds a /whois frontend page and a zone
sidebar modal to display registrar, dates, nameservers and status.
2026-04-16 15:22:51 +07:00
e0dc19614f checker: enforce MaxChecksPerDay quota with interval-aware throttling
Some checks failed
continuous-integration/drone/push Build is failing
Wire UserQuota.MaxChecksPerDay field into the scheduler via the
UserGater: an in-memory daily counter per user
(reset at UTC midnight): gates scheduled executions, with a two-tier
heuristic that skips short-interval jobs first once the budget is 80%
consumed so rare/important checks are not starved by frequent
pings. Planned executions returned by ListPlannedExecutions are marked
with a new ExecutionRateLimited status when the user is over
budget. Manual API triggers bypass the quota.
2026-04-16 15:18:43 +07:00
98642bf7e7 checkers: add NoOverride field support for checker options
Prevent more specific scopes from overriding option values locked at a
higher scope (e.g. admin). Includes defense-in-depth stripping on
Set/Add operations, merge-time preservation, and frontend filtering.
2026-04-16 15:18:43 +07:00
33ef6b60e7 web: add checks status summary badge to zone viewer PageHeader
Add a ChecksSummaryBadge component that fetches domain-level checker statuses
and displays the worst status as a colored badge linking to the checks page.
2026-04-16 15:18:43 +07:00
439fe2a2e9 checkers: show worst check status badge on domain list
Add DomainWithCheckStatus model and GetWorstDomainStatuses usecase to
compute the most critical checker status per domain. The GET /domains
endpoint now returns status alongside each domain. The frontend domain
store, list components, and table row display dynamic status badges
with color and icon instead of a hardcoded "OK".

ZoneList is made generic (T extends HappydnsDomain) so the badges
snippet preserves the caller's concrete type without unsafe casts.
2026-04-16 15:18:43 +07:00
fb02331f41 checkers: show children checkers on domain page and hide scheduling for non-domain checkers
Add a separate section on the domain checks page to display zone and
service-level checkers that can be configured but won't produce results
at the domain scope. Hide the scheduling and rules cards when configuring
a non-domain checker from the domain context.
2026-04-16 15:18:43 +07:00
4e034b0135 checkers: integrate rules as a view tab in execution detail page
Remove separate /rules pages and display rules as a tab alongside
metrics, HTML, and JSON views. Rules become the default view when
no metrics or HTML report is available. Status is now shown as a
colored badge in the rules table.
2026-04-16 15:18:43 +07:00
322ade2881 checkers: add frontend metrics chart on execution pages
Add Chart.js-based line chart for checker metrics. The chart appears
on the executions list page (aggregated) and on individual execution
detail pages. Metrics view mode is selectable via the sidebar alongside
HTML report and raw JSON views.
2026-04-16 15:18:43 +07:00
b37ed1d349 checkers: add HTML report rendering for observation providers
Introduce CheckerHTMLReporter interface that observation providers can
implement to render rich HTML documents from their data. The Zonemaster
provider implements it with collapsible accordions and severity badges.

Adds API endpoint GET .../observations/:obsKey/report, frontend stores
for view mode switching (HTML/JSON), and wires the sidebar toggle buttons.
2026-04-16 15:18:43 +07:00
7a4de13ac6 checkers: add frontend UI components and routes
Add all checker UI pages and components:
- Checker list, config, schedule, and rules pages
- Execution list, detail, results, and rules pages
- Sidebar components for domain/service checker status
- Run check modal with option overrides and rule selection
- Domain-scoped and service-scoped check routes
- Admin pages for checker configuration and scheduler management
- Header navigation link for checkers section
2026-04-16 15:18:43 +07:00
ee560a699d checkers: add frontend API client, stores, and utilities
Add the frontend infrastructure for the checker UI:
- API client with scoped helpers for domain/service-level operations
- Svelte stores for checker state (currentExecution, currentCheckInfo)
- Utility functions for status colors, icons, i18n keys, date formatting
- Shared helpers: withInheritedPlaceholders, downloadBlob, collectAllOptionDocs
- English translations for all checker UI strings
- Zone model and form types extended for checker support
2026-04-16 15:18:43 +07:00
exyone
9a3f834129 Improve Chinese translation and fix English translation errors (manually translated)
Add Esperanto, Manchu, and Tibetan translations (AI-assisted with manual review)
2026-04-16 02:14:18 +07:00
90e4d30ae4 web: Make images occupy the background
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-14 09:08:47 +07:00
3163a10c45 web: add collapsible domain groups with persistent state
All checks were successful
continuous-integration/drone/push Build is passing
Add click-to-collapse and double-click-to-solo behavior on group
headers in ZoneList, with a chevron indicator. Collapsed state is
persisted in localStorage and cleared on login/logout.
2026-04-14 05:08:01 +07:00
197fd9c796 Redesign UI: modernize layout, login, resolver, and some components
Refresh the overall visual design across the frontend: floating labels
and centered card layout for auth pages, animated sidebar+results view
for the resolver, polished dropdown menus, toasts, and feedback widget,
and cleaner global styles (navbar shadow, border, transitions).
2026-04-14 05:08:01 +07:00
52e176c73a chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-13 00:12:13 +00:00
effb588d3c fix: use one-way binding for record line rr prop
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-11 12:25:10 +07:00
de6eb2b3b4 fix: add missing fields to zone mock in thiszone test
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is failing
The mock zone object was missing `services` and `last_modified` fields
required by the response transformer, causing Object.keys to fail on
undefined.
2026-04-05 22:23:52 +07:00
8e2e38757f fix: guard against undefined entry in domainLink helper
Some checks failed
continuous-integration/drone/push Build is failing
Add null checks to prevent runtime errors when the domain index entry
does not exist for the given identifier.
2026-04-05 22:08:46 +07:00
397e19b745 fix(deps): update module @hey-api/openapi-ts to v0.95.0
Some checks failed
continuous-integration/drone/push Build is failing
2026-04-04 22:22:06 +07:00
cae8658f61 web: Tighten TypeScript types and fix toast API across frontend
Replace `any` with precise types (unknown, Record<string, any>, specific
interfaces) in props, function signatures, and index signatures. Introduce
ServiceWithValue to bridge SDK's HappydnsService.Service from unknown to
its runtime shape. Simplify updateDomain to take explicit id + body params.
2026-04-04 22:22:06 +07:00
f92cab2abf web: Prefer pointer as grab in ZoneList 2026-04-04 22:16:27 +07:00
30506e9731 web: Fix state_referenced_locally warning in ZoneList
Replace $state + $effect pattern with $derived for localDomains to properly react to prop changes. Also reformat genGroups signature and sort callback indentation.
2026-04-04 22:16:27 +07:00
15f014cf5a web: Replace null defaults with undefined for optional props
Aligns optional prop types and defaults with TypeScript/Svelte 5 idioms
by dropping explicit null in favor of undefined throughout components.
2026-04-04 22:16:27 +07:00
b2e85cb9f2 web: Fix variable not declared as $state 2026-04-04 22:16:27 +07:00
2679d0476e web: Fix a11y role 2026-04-04 22:16:27 +07:00
fa47e9b4b1 web: Replace ServiceCombined with HappydnsService SDK type across frontend 2026-04-04 22:16:27 +07:00
17c9e88903 web: Derive local model types from SDK-generated types to strengthen type checking
Replace hand-written interfaces with types derived from SDK-generated types
(alias, Required<>, Omit<> & extend) so the two type systems stay in sync.
This eliminates all `as any` casts and reduces `as unknown as` casts from 13
to 9 in the API wrapper layer.
2026-04-04 22:16:27 +07:00
e09044388b web: Move delete_in_progress UI state from Session model to component
Replace the delete_in_progress field on the Session interface with a
local Set<string> in SessionsManager, keeping model types pure.
2026-04-04 22:05:28 +07:00
3e3b23a0c4 Replace any types with proper TypeScript types in web API and model files 2026-04-04 22:05:28 +07:00
e30d1a5f50 Add is_auth_user endpoint in swagger doc and remove custom client call in frontend 2026-04-04 22:05:28 +07:00
4f3a1d7f7b Add format:"date-time" struct tags to time.Time model fields 2026-04-04 22:05:28 +07:00
d600bbcbd9 web: Refactor domain Table component to improve single responsibility
Extract DomainTableRow and ProviderLink components from the monolithic
Table.svelte, which was mixing table structure, provider name resolution,
row navigation, and action button logic into a single component.
2026-03-30 11:58:02 +07:00
e103d2262a Add DNS propagation time tracking per service
After publishing zone corrections, compute and store a PropagatedAt
timestamp on each affected service indicating when old cached records
will have expired. For updated/deleted services, this is publish_time +
old service TTL. For new services, it uses the SOA minimum TTL
(negative cache duration), falling back to the zone's DefaultTTL.

The propagation detection reuses the same service matching technique as
ReassociateMetadata (subdomain + type + ServiceRDataHash). Both the
published snapshot and the WIP zone are stamped.
2026-03-30 11:58:02 +07:00