Use the Page Visibility API to pause toast countdowns and progress bar
animations when the tab is hidden, and resume them when the user returns.
New toasts created while the page is hidden also start in a paused state.
Move the domainLink helper from local component functions into the
domains store so it can be reused across layout, sidebars, and page
components.
This fixes links to non-unique domain names.
Add/update/delete service calls in the Service facade were bypassing
ActionOnEditableZone, so mutations could silently target a committed or
published zone instead of deriving a new editable snapshot first.
Wraps AddServiceToZone, RemoveServiceFromZone, and UpdateZoneService
with ActionOnEditableZone so the decorator is applied consistently.
Fixes regression introduced by b2b6467575.
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.
When display_by_groups is enabled, domains are now draggable and group
containers act as drop targets. Dropping a domain onto a different group
updates its group via the API and refreshes the domain list.
The next query parameter was silently dropped when users chose OIDC
login, always redirecting to / after authentication. Forward the
validated next value to /auth/oidc, store it in the session during
redirect, and use it for the final redirect in the callback, matching
the behaviour of password-based login.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Decode and validate the next query parameter before navigating,
ensuring it is a same-origin relative path (starts with / but not //)
to prevent attackers from redirecting users to external sites after login.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The function silently fell back to creating a new session when session.id
was falsy, which could create unintended API tokens from a partial object.
Session creation is already handled by addSession(); updateSession() now
throws early when no id is present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
SHA-1 is cryptographically broken. Replace with SHA-256 and slice to
the first 6 bytes (12 hex chars) for a compact, human-readable token
fingerprint. 48 bits is more than sufficient to distinguish a handful
of active sessions without sacrificing readability.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces ProviderPicker and PickProvider reusable components so that
adding a domain from NewDomainInput or FilterDomainInput opens an
inline provider-selection modal instead of navigating away to
/domains/new/:dn.
Replace the ListGroup-based provider list with a Bootstrap Table on the
providers page. Rows are clickable to edit, the domain count links to
the domains page pre-filtered by provider, and action buttons handle
propagation correctly.
Replace the dedicated provider type selection page with a modal,
using a module-level controller pattern. The /providers/new route
now redirects to /providers?newProvider, which auto-opens the modal.
Introduces a reusable PageTitle component with a teal overline accent,
display-3 heading, optional monospace domain label, subtitle, and a
children slot for future domain health/check badges. Applied consistently
to the zone viewer, history, logs, export, import, resolver, providers,
account settings, and new-domain pages.
Introduce ServiceDetailsOffcanvas, an offcanvas panel that opens when
clicking a service card. It displays the service description, its DNS
records, and provides actions buttons.
Also remove raw DNS record from service form.
Install highlight.js and apply DNS zone file syntax highlighting on the
export page and in the RecordText component. Uses the github theme and
imports only the dns language to keep the bundle small.
Convert the zone file viewer from a modal dialog to a dedicated page at
/domains/[dn]/export, following the same pattern used for service pages.
Adds a "Copy to clipboard" button in the page title bar and adds the
common.copy-clipboard translation key to all supported locales.