Commit graph

128 commits

Author SHA1 Message Date
30ec8c2c09 Implement backend model for test results and schedule 2026-03-17 19:21:51 +07:00
e98ad199da Add checker routes to API + refactor check controller 2026-03-17 19:21:51 +07:00
de549616db Implement checker options retrieval 2026-03-17 19:21:51 +07:00
963ce8184b Add usescases to handle checkers 2026-03-17 19:21:51 +07:00
5351c9edd0 Load checks plugins 2026-03-17 19:21:51 +07:00
a7b225b9df Rework zone diff/apply flow: separate diff from provider API, support partial apply
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.
2026-03-16 19:46:09 +07:00
36a7d8e9d3 Fix email validation HMAC weakness and prevent user enumeration on registration 2026-03-16 19:44:14 +07:00
c850cfb0db Refactor orchestrator: add context.Context, fix error handling, use interfaces
- Handle AppendDomainLog errors with log.Printf instead of silently discarding
- Add NoopDomainLogAppender for null object pattern
2026-03-16 19:44:14 +07:00
2572e8c319 Preserve service metadata across zone re-analyses
After AnalyzeZone rebuilds services from raw DNS records, metadata that
cannot be derived from DNS (Id, UserComment, OwnerId, Aliases, TTL, and
service-specific fields like OpenPGP/SMimeCert Username) was lost.

Add a post-processing function ReassociateMetadata that matches new
services to old ones by type and subdomain (using RDATA hashing for
disambiguation) and transfers metadata. Services opt in to body-level
transfer via the new MetadataEnricher interface.
2026-03-14 11:06:49 +07:00
f4bcb1c9cf refactor: decompose Analyzer into recordPool and serviceAccumulator
Restructure the service analyzer architecture to improve maintainability:

- Extract recordPool (zone records + mark-delete claiming) and
  serviceAccumulator (service registry + domain normalization) as
  embedded structs in Analyzer
- Replace swap-delete with mark-delete to eliminate mutation-during-iteration
- Centralize domain normalization using helpers.DomainRelative
- Make Comment/NbResources lazy via Service.MarshalJSON instead of
  eager assignment at three separate call sites
- Extract SPF merging from usecase layer into services.CollectAndMergeSPF
- Add GetDefaultTTL accessor and comprehensive Analyzer doc comments
- Add round-trip test infrastructure covering MX, CNAME, CAA, TXT, SPF,
  DMARC, GSuite, Origin, Server and more
2026-03-14 11:06:49 +07:00
31950811c0 Merge SPF records from multiple services into single TXT record
RFC 7208 requires exactly one SPF record per domain. Previously, the
standalone SPF service and provider services like GSuite each emitted
their own SPF TXT record, producing invalid DNS when both existed.

Introduce SPFContributor interface so services can declare SPF
directives independently. At zone generation time, all contributions
for the same domain are merged into a single SPF record with the
strictest "all" policy winning. During zone import, GSuite claims its
directive via ClaimSPFDirective so the SPF analyzer excludes it from
the standalone SPF service.
2026-03-14 10:36:53 +07:00
b0b79efceb security: decouple failure tracking from captcha provider
Previously, RecordFailure/RecordSuccess were only called when a captcha
provider was configured, making brute-force tracking entirely inactive
on deployments without one.

- Always track login failures and successes regardless of captcha config
- When threshold is crossed with a captcha provider: 401 + captcha_required (existing behaviour)
- When threshold is crossed without a captcha provider: 429 + rate_limited flag
- Frontend: show a rate-limited message and disable the submit button on 429
- Add errors.rate-limited translation key to all locales

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 15:03:49 +07:00
c16e9c243f Transparently rehash passwords with outdated bcrypt cost on login
Add a bcryptCost constant to centralize the target cost (12), a
NeedsRehash() method that checks the stored hash cost via bcrypt.Cost(),
and trigger a transparent rehash in AuthenticateUserWithPassword when
the stored hash is below the current target.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 13:06:20 +07:00
46a5d15aa4 security: increase bcrypt cost from default (10) to 12
OWASP now recommends bcrypt cost >= 12. Using the implicit default cost
of 0 (which maps to 10) is below current recommendations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 13:06:20 +07:00
043b81a350 security: enforce 72-character maximum password length
bcrypt silently truncates input at 72 bytes. Without an explicit maximum,
a user could set a 200-char password and log in with only the first 72
chars, and very long passwords could be used for a CPU-based DoS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 13:06:20 +07:00
ee0e22adf5 chore: apply Go naming conventions and minor code improvements 2026-03-01 17:38:12 +07:00
f457071d5d chore: replace interface{} with any across the codebase
Use the modern Go type alias `any` instead of `interface{}` throughout
all packages for improved readability and consistency with current Go idioms.
2026-03-01 17:38:04 +07:00
c9552fa9b2 Remove UsecaseDependancies service locator pattern
All checks were successful
continuous-integration/drone/push Build is passing
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.
2026-02-14 10:49:46 +07:00
e0d8526577 Add Altcha captcha provider support
Some checks are pending
continuous-integration/drone/push Build is running
2026-02-13 12:29:14 +07:00
0090054324 Add CAPTCHA support for login and registration
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.
2026-02-13 11:31:37 +07:00
bee17f7761 Add missing json tag on all structs for better OpenAPI generation 2026-01-26 12:34:55 +08:00
2d39de5eb9 Add service initialization endpoint with DNS type detection
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.
2026-01-12 10:19:33 +07:00
6add2f220e Refactor storage layer to use key-value template pattern
All checks were successful
continuous-integration/drone/tag Build is passing
Extract common key-value storage operations into internal/storage/kvtpl/
template directory. This consolidates duplicated logic from both leveldb
and inmemory implementations into reusable generic functions.

Key changes:
- Create kvtpl/ package with generic KV storage operations
- Consolidate iterator implementation using generics
- Update migration functions to use new template structure
- Refactor tests to work with new storage interface

This prepares the codebase for easier addition of new storage backends
by providing a consistent template layer.
2026-01-09 17:17:04 +07:00
21b9072bba Add comprehensive test coverage for model package 2026-01-09 15:34:31 +07:00
ae0f9018bb Can add and update records in service 2026-01-09 15:01:51 +07:00
f5911cb256 Can delete a record in a service 2026-01-08 18:15:37 +07:00
437cf4d80b Create copy of returned records 2026-01-07 22:26:19 +07:00
df825f1f50 Services stores records instead of abstact data 2026-01-07 22:26:19 +07:00
d6e49e0440 Update go modules and dnscontrol to v4.29.0 2025-12-24 19:03:33 +07:00
8fa8efcefc insights: Send stats about users' settings
Some checks failed
continuous-integration/drone/push Build is failing
2025-06-12 20:07:57 +02:00
ebb5d34be5 Use ListRecordsUC when generating zonefile 2025-06-10 09:53:44 +02:00
ce91b49a73 Create a usecase from API to extract domain creation on provider
Fixes a security issue where a user can create a domain on a provider
while DisableProviders option was set
2025-06-09 15:38:11 +02:00
b0e0ab6d9e Create a usecase from provider controller 2025-06-09 15:38:11 +02:00
f63860af83 Can create domain directly on the provider if supported
All checks were successful
continuous-integration/drone/push Build is passing
Closes: https://github.com/happyDomain/happydomain/issues/24
2025-05-28 23:02:22 +02:00
b527e0ed26 Refactor usecases: create intermediate structs to facilitate tests 2025-05-28 23:02:22 +02:00
b2b6467575 Refactor domain/provider/zone usecase: split in multiple files 2025-05-28 23:02:22 +02:00
1408e04f45 Refactor domain's logs usecase: split in multiple files 2025-05-28 23:02:22 +02:00
0495ab4693 Refactor auth_user usecase: split in multiple files 2025-05-28 23:02:22 +02:00
cffbc104ae Refactor session usecase: split in multiple files 2025-05-28 22:00:02 +02:00
356e733e76 Move config struct to model, avoid dependancy to storage 2025-05-28 22:00:02 +02:00
b575a17674 Improve error report 2025-05-28 22:00:02 +02:00
e186a33f89 refactor: Move storage interfaces to usecases 2025-05-28 22:00:02 +02:00
b77e2b8c3a Refactor App to add clarity 2025-05-22 15:46:06 +02:00
fb971236f9 Rename Service to Usecase to be consistent 2025-05-22 15:46:06 +02:00
2f21ebee44 Rename ProviderId attribute 2025-05-22 15:46:06 +02:00
2e9b9e6adf Standardize databases errors 2025-05-22 15:46:06 +02:00
5d0fe5edb5 Remove plural structs not used as struct 2025-05-22 15:46:06 +02:00
d427ef4377 Move tidy operation to a usecase 2025-05-22 15:46:05 +02:00
401ba892f7 Use iterators in return to ListAll database functions 2025-05-22 15:46:05 +02:00
f4daca892e Simplify database calls and move the logic in usecases: providers 2025-05-22 15:46:05 +02:00