Simplify setup flow and public API docs

This commit is contained in:
StasonJatham committed 2026-05-21 17:58:20 +02:00
1 parent 2e401124e8
commit 97a76aa91e
12 files changed
+119 -140

No files matched your search

+55 -9
View File
@@ -3,9 +3,11 @@ from __future__ import annotations
from ..services.ddns import DdnsService
from ..settings import DdnsSettings
from .components import (
_code_window,
_copy_menu,
_copy_row,
_event_label,
_example_update_ips,
_fritzbox_fields,
_manual_update_commands,
_manual_update_panel,
@@ -13,7 +15,6 @@ from .components import (
)
from .html_utils import SafeHtml, attr, escape, trusted
from .layout import _page, _top_nav
from .templates_public_sections import _created_hostname_panel
def _render_management_page(
@@ -23,7 +24,6 @@ def _render_management_page(
account: dict[str, str | int | None],
csrf_token: str,
message: str | None = None,
created_account: dict[str, str] | None = None,
request_ip: str | None = None,
) -> str:
account_for_url = {
@@ -43,7 +43,6 @@ def _render_management_page(
<tr><td colspan="6" class="empty">No router updates yet.</td></tr>
"""
message_html = _management_message(message)
rotated_links = _created_hostname_panel(service, created_account, request_ip)
dashboard_password_panel = _dashboard_password_panel(management_slug, csrf_token, bool(account.get("dashboard_password_hash")))
return _page(
"KarlDNS management",
@@ -59,7 +58,6 @@ def _render_management_page(
</div>
</section>
{message_html}
{rotated_links}
<section class="section">
<div class="container">
<div class="row g-4 align-items-start">
@@ -149,18 +147,31 @@ def _render_management_page(
)
def _render_pending_management_page(
service: DdnsService,
settings: DdnsSettings,
management_slug: str,
account: dict[str, str | int | None],
csrf_token: str,
message: str | None = None,
request_ip: str | None = None,
) -> str:
hostname = escape(account["hostname"])
raw_hostname = str(account["hostname"])
account_for_url = {
"hostname": raw_hostname,
"update_slug": str(account["update_slug"]),
"management_slug": management_slug,
}
update_url = service.fritz_update_url(account_for_url)
registration_url = service.registration_url({"management_slug": management_slug})
dashboard_url = service.dashboard_url({"management_slug": management_slug})
hostname = escape(raw_hostname)
message_html = _management_message(message)
cleanup_hours = settings.cleanup_pending_account_hours
cleanup_text = f"{cleanup_hours} hours" if cleanup_hours != 24 else "24 hours"
manual_commands = _manual_update_commands(update_url, request_ip)
example_ipv4, example_ipv6 = _example_update_ips(request_ip)
return _page(
"Register hostname",
"KarlDNS setup",
trusted(f"""
<main id="main">
{_top_nav()}
@@ -168,7 +179,7 @@ def _render_pending_management_page(
<div class="container text-center d-grid justify-items-center gap-3">
<p class="eyebrow">Pending setup</p>
<h1>{hostname}</h1>
<p class="lead">Register this hostname after you have copied the private values. Unregistered setups are cleaned up after {escape(cleanup_text)}.</p>
<p class="lead">Save these values, then register the hostname. Pending setups are cleaned up after {escape(cleanup_text)}.</p>
<form method="post" action="/m/{attr(management_slug)}/activate">
<input type="hidden" name="csrf" value="{attr(csrf_token)}">
<button class="btn btn-primary rounded-pill" type="submit">Register hostname</button>
@@ -176,9 +187,44 @@ def _render_pending_management_page(
</div>
</section>
{message_html}
<section class="section">
<div class="container narrow d-grid gap-4">
<div>
<p class="eyebrow">Save</p>
<h2>Your values.</h2>
<p class="section-copy">This page is private. You can revisit it while the setup is pending. After registration, the dashboard hides secrets by default.</p>
<p class="section-copy"><strong>Public:</strong> hostname and CNAME target. <strong>Secret:</strong> update URL, register URL, and private dashboard.</p>
</div>
<div class="d-grid gap-2">
{_copy_row("Update-URL:", update_url, "Secret", mask_secret=False)}
{_copy_row("Domainnamen:", raw_hostname, "Public")}
{_copy_row("Register URL:", registration_url, "Secret", mask_secret=False)}
{_copy_row("Private dashboard:", dashboard_url, "Secret", mask_secret=False)}
{_copy_row("CNAME target:", raw_hostname, "Public")}
</div>
<form method="post" action="/m/{attr(management_slug)}/activate">
<input type="hidden" name="csrf" value="{attr(csrf_token)}">
<button class="btn btn-primary rounded-pill" type="submit">Register hostname</button>
</form>
</div>
</section>
<section class="section section-compact">
<div class="container narrow text-center">
<p class="section-copy mx-auto">Lost the first page? Create a new hostname. Private URLs are shown only once.</p>
<div class="container narrow d-grid gap-4">
<div>
<p class="eyebrow">FRITZ!Box</p>
<h2>Router setup.</h2>
<p class="section-copy">Paste this exact URL into the FRITZ!Box <strong>Update-URL</strong> field. Use <strong>{hostname}</strong> as <strong>Domainnamen</strong>. No KarlDNS username or password is needed; if your router requires them, enter any placeholder.</p>
{_code_window(update_url, copy_label="FRITZ!Box update URL", class_name="mt-3")}
</div>
<div>
<h2>Manual updates.</h2>
<p class="section-copy">Scripts can send the IP explicitly, or omit it and let KarlDNS use the request IP. Your current public examples use <code>{escape(example_ipv4)}</code> and <code>{escape(example_ipv6)}</code> where available.</p>
{_code_window(manual_commands, copy_label="manual update commands", class_name="mt-3")}
</div>
<div>
<h2>Use your own DNS name.</h2>
<p class="section-copy">Create a CNAME at your DNS provider that points to <strong>{hostname}</strong>. KarlDNS only updates this generated hostname.</p>
</div>
</div>
</section>
</main>