Introduce a DomainAvailabilityWatch entity (model, storage, usecase and
REST endpoints) letting a user track a domain they do not own and get
notified the moment it becomes available for registration. A dedicated
domain_availability checker reads WHOIS/RDAP via pkg/domaininfo and inverts
the status (OK while registered, Crit once free) so the existing dispatcher
fires exactly once on the transition. The scheduler enumerates watches and
enqueues the check, carrying the watch id in CheckTarget.DomainId; autofill
and notification payloads fall back to the watch store to resolve the name.
Watches are included in per-user backup/restore. The web UI adds an
availability watchlist page and navigation entry.
Refactors the admin backup usecase to share per-user collection logic
via backupOneUser(), then adds BackupUser() which filters system-wide
collections (checker configs, plans, evaluations, executions, discovery)
down to the requesting user by UserId.
Wires the backup usecase into the public API dependency graph and adds
a download button in the /me settings page near the delete-account
section.
Rename internal/{checker,service,provider,notification} to
internal/{dnschecker,serviceanalyzer,providerregistry,notifier} so
imports no longer collide with the same-named usecase subpackages and
no longer require import aliases to disambiguate.
Adds a backend endpoint that resolves the RFC 7489 sec. 7.1 cross-domain
reporting authorization record, paired with the (incoming) DMARC async
validator on the front-end.
When a DMARC record at example.com publishes rua=mailto:dmarc@third.tld,
third-party receivers MUST refuse to deliver reports unless
example.com._report._dmarc.third.tld publishes a v=DMARC1 TXT. This is
the silent failure mode behind most "we configured DMARC but never see
any report" tickets.
Adds a backend endpoint that fetches and parses an MTA-STS policy
file at https://mta-sts.<domain>/.well-known/mta-sts.txt per RFC 8461
sec. 3.3, paired with the (existing) MTA-STS TXT validator on the front-end.
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.
The /api/domaininfo/:domain route is unauthenticated and proxies
outbound RDAP/WHOIS queries, making it an abuse vector. Add a
per-IP rate limiter (10 req/min) using gin-rate-limit to mitigate
enumeration and proxy abuse while keeping the endpoint public.
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.
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.
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.
Observation providers can now implement CheckerMetricsReporter to
extract time-series metrics from their stored data. The controller
returns the metrics as a JSON array.
Routes: user-level (/api/checkers/metrics), domain-level, per-checker,
and per-execution.
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.
Wire up the checker system to the HTTP layer:
- API controllers for checker operations, options, plans, and results
- Scoped routes at domain and service level
- Admin controllers for checker config and scheduler management
- App initialization: create usecases, start/stop scheduler
- Zone controller updated to include per-service check status
Decouple diff computation from executable provider closures by fetching
provider records and computing diffs locally via DNSControlDiffByRecord.
On apply, build a target record set from user-selected corrections using
BuildTargetRecords, then ask the provider for executable corrections
against that target. A published snapshot is inserted at ZoneHistory[1]
while the WIP zone at position 0 remains unchanged.
Expose service editors publicly (no auth required) at /generator for
SEO discoverability. Each page shows an interactive editor alongside
a live DNS zone record preview powered by a new POST
/service_specs/:ssid/records backend endpoint.
Replace the UsecaseDependancies interface with plain Dependencies structs
defined locally in each route package. DeclareRoutes acts as the sole
composition root where use cases are resolved; sub-route functions and
controllers receive only the specific interfaces they need.
Integrates optional bot protection on the registration endpoint (always
required when a provider is configured) and the login endpoint (triggered
after N consecutive failures for the same IP or email address).
Supported providers: hCaptcha, reCAPTCHA v2, Cloudflare Turnstile.
Implement backend-driven service initialization to replace hazardous
frontend initialization logic. Services can now provide custom
initialization via ServiceInitializer interface or get sensible
defaults automatically.
- Moved usecases into internal/usecase
- Renamed internal/utils to internal/helpers for better naming semantics
- Clarified separation between domain model, usecases, adapters, and web/API