Archived
Align hostname choice layout
This commit is contained in:
1 parent
2966a69331
commit
12fb14984c
3 files changed
+41
-35
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 576 KiB After Width: | Height: | Size: 660 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 442 KiB After Width: | Height: | Size: 420 KiB |
+41
-35
@@ -664,23 +664,42 @@ def _render_public_home(
|
|||||||
{created_html}
|
{created_html}
|
||||||
<section class="section" id="create">
|
<section class="section" id="create">
|
||||||
<div class="container narrow">
|
<div class="container narrow">
|
||||||
<div class="row g-4 align-items-center">
|
<div class="text-center mb-4">
|
||||||
<div class="col-lg-6">
|
<p class="eyebrow">Choose your hostname</p>
|
||||||
<p class="eyebrow">Create in one step</p>
|
|
||||||
<h2>No account. No login.</h2>
|
<h2>No account. No login.</h2>
|
||||||
<p class="section-copy">The generated URL is the secret. FRITZ!Box replaces <code><ipaddr></code> and calls it when your public IP changes.</p>
|
<p class="section-copy mx-auto">Use a generated KarlDNS hostname immediately, or verify your own domain with a DNS TXT record.</p>
|
||||||
|
</div>
|
||||||
|
<div class="row g-4 align-items-stretch">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card card-body h-100 gap-3">
|
||||||
|
<p class="eyebrow">Use our domain</p>
|
||||||
|
<h3>Generate a KarlDNS hostname</h3>
|
||||||
|
<p class="section-copy mb-0">KarlDNS generates the hostname, secret update URL, and optional router compatibility credentials automatically.</p>
|
||||||
|
<form method="post" action="/magic" class="d-grid gap-3" aria-label="Create a generated DynDNS hostname">
|
||||||
|
<button type="submit" class="btn btn-primary rounded-pill">Generate hostname</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card card-body h-100 gap-3">
|
||||||
|
<p class="eyebrow">Use your own domain</p>
|
||||||
|
<h3>Verify DNS ownership</h3>
|
||||||
|
<p class="section-copy mb-0">Add one TXT record so KarlDNS can confirm you control the domain before it publishes A/AAAA records there.</p>
|
||||||
|
<form method="post" action="/request-domain" class="d-grid gap-3" aria-label="Request a custom domain TXT challenge">
|
||||||
|
<label>Domain
|
||||||
|
<input class="form-control" name="domain" placeholder="example.com" autocomplete="off" autocapitalize="none" spellcheck="false" required>
|
||||||
|
</label>
|
||||||
|
<button type="submit" class="btn btn-primary rounded-pill">Create TXT challenge</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="terminal-card mt-4" aria-hidden="true">
|
<div class="terminal-card mt-4" aria-hidden="true">
|
||||||
<div class="terminal-dots"><span></span><span></span><span></span></div>
|
<div class="terminal-dots"><span></span><span></span><span></span></div>
|
||||||
<code>$ curl -sS 'https://karldns.de/u/<secret>?myip=203.0.113.10'</code>
|
<code>$ curl -sS 'https://karldns.de/u/<secret>?myip=203.0.113.10'</code>
|
||||||
<code>good 203.0.113.10</code>
|
<code>good 203.0.113.10</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="/magic" class="col-lg-5 card card-body gap-3" aria-label="Create a generated DynDNS hostname">
|
|
||||||
<p class="section-copy mb-0">KarlDNS generates the hostname, secret update URL, and optional router compatibility credentials automatically.</p>
|
|
||||||
<button type="submit" class="btn btn-primary rounded-pill">Generate hostname</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
<section class="section" id="manual-updates">
|
<section class="section" id="manual-updates">
|
||||||
<div class="container narrow text-center">
|
<div class="container narrow text-center">
|
||||||
@@ -729,9 +748,10 @@ def _top_nav(label: str | None = None, links: str = "") -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _custom_domain_flow(service: DdnsService, challenge: dict[str, str | None] | None, message: str | None) -> str:
|
def _custom_domain_flow(service: DdnsService, challenge: dict[str, str | None] | None, message: str | None) -> str:
|
||||||
|
if not challenge:
|
||||||
|
return ""
|
||||||
challenge_html = ""
|
challenge_html = ""
|
||||||
create_form = ""
|
create_form = ""
|
||||||
if challenge:
|
|
||||||
domain = html.escape(str(challenge["domain"]))
|
domain = html.escape(str(challenge["domain"]))
|
||||||
token = str(challenge["token"])
|
token = str(challenge["token"])
|
||||||
claim_secret = html.escape(str(challenge.get("claim_secret") or ""))
|
claim_secret = html.escape(str(challenge.get("claim_secret") or ""))
|
||||||
@@ -740,9 +760,9 @@ def _custom_domain_flow(service: DdnsService, challenge: dict[str, str | None] |
|
|||||||
status = html.escape(message or "Add this TXT record at your DNS provider, then check when it has propagated.")
|
status = html.escape(message or "Add this TXT record at your DNS provider, then check when it has propagated.")
|
||||||
txt_bundle = f"TXT name: {verification_name}\nTXT value: {token}"
|
txt_bundle = f"TXT name: {verification_name}\nTXT value: {token}"
|
||||||
challenge_html = f"""
|
challenge_html = f"""
|
||||||
<div class="col-md-4">
|
<div class="col-lg-5">
|
||||||
<div class="card card-body h-100 gap-3">
|
<div class="card card-body h-100 gap-3">
|
||||||
<span class="badge text-bg-primary rounded-circle align-self-start">2</span>
|
<span class="badge text-bg-primary rounded-circle align-self-start">1</span>
|
||||||
<h3>Add the TXT record</h3>
|
<h3>Add the TXT record</h3>
|
||||||
<p class="small text-secondary mb-0 mt-2">{status}</p>
|
<p class="small text-secondary mb-0 mt-2">{status}</p>
|
||||||
<div class="alert alert-info mb-0 py-2 small">TXT name and value are public DNS records. The private claim link is secret.</div>
|
<div class="alert alert-info mb-0 py-2 small">TXT name and value are public DNS records. The private claim link is secret.</div>
|
||||||
@@ -760,9 +780,9 @@ def _custom_domain_flow(service: DdnsService, challenge: dict[str, str | None] |
|
|||||||
"""
|
"""
|
||||||
if challenge.get("verified_at"):
|
if challenge.get("verified_at"):
|
||||||
create_form = f"""
|
create_form = f"""
|
||||||
<div class="col-md-4">
|
<div class="col-lg-5">
|
||||||
<div class="card card-body h-100 gap-3">
|
<div class="card card-body h-100 gap-3">
|
||||||
<span class="badge text-bg-primary rounded-circle align-self-start">3</span>
|
<span class="badge text-bg-primary rounded-circle align-self-start">2</span>
|
||||||
<h3>Create router hostname</h3>
|
<h3>Create router hostname</h3>
|
||||||
<form method="post" action="/accounts" class="d-grid gap-3" aria-label="Create custom-domain router credentials">
|
<form method="post" action="/accounts" class="d-grid gap-3" aria-label="Create custom-domain router credentials">
|
||||||
<input type="hidden" name="mode" value="custom">
|
<input type="hidden" name="mode" value="custom">
|
||||||
@@ -778,9 +798,9 @@ def _custom_domain_flow(service: DdnsService, challenge: dict[str, str | None] |
|
|||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
create_form = """
|
create_form = """
|
||||||
<div class="col-md-4">
|
<div class="col-lg-5">
|
||||||
<div class="card card-body h-100 gap-3 opacity-75">
|
<div class="card card-body h-100 gap-3 opacity-75">
|
||||||
<span class="badge text-bg-primary rounded-circle align-self-start">3</span>
|
<span class="badge text-bg-primary rounded-circle align-self-start">2</span>
|
||||||
<h3>Create router hostname</h3>
|
<h3>Create router hostname</h3>
|
||||||
<p class="small text-secondary mb-0 mt-2">This unlocks after the TXT record is visible in public DNS.</p>
|
<p class="small text-secondary mb-0 mt-2">This unlocks after the TXT record is visible in public DNS.</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -789,27 +809,13 @@ def _custom_domain_flow(service: DdnsService, challenge: dict[str, str | None] |
|
|||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
<section class="section" id="custom-domain">
|
<section class="section" id="custom-domain">
|
||||||
<div class="container">
|
<div class="container narrow">
|
||||||
<div class="d-flex align-items-md-center justify-content-between gap-4 flex-column flex-md-row">
|
<div class="text-center">
|
||||||
<div>
|
|
||||||
<p class="eyebrow">Direct custom-domain publishing</p>
|
<p class="eyebrow">Direct custom-domain publishing</p>
|
||||||
<h2>Verify DNS ownership</h2>
|
<h2>Verify DNS ownership</h2>
|
||||||
<p class="section-copy">Use this only when KarlDNS should publish A/AAAA records directly inside your domain. If you just want your own subdomain, generate a hostname above and create a CNAME to it.</p>
|
<p class="section-copy mx-auto">Use this only when KarlDNS should publish A/AAAA records directly inside your domain. If you just want your own subdomain, generate a hostname above and create a CNAME to it.</p>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row g-3 mt-4">
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card card-body h-100 gap-3">
|
|
||||||
<span class="badge text-bg-primary rounded-circle align-self-start">1</span>
|
|
||||||
<h3>Enter domain</h3>
|
|
||||||
<form method="post" action="/request-domain" class="d-grid gap-3" aria-label="Request a custom domain TXT challenge">
|
|
||||||
<label>Domain
|
|
||||||
<input class="form-control" name="domain" placeholder="example.com" autocomplete="off" autocapitalize="none" spellcheck="false" required>
|
|
||||||
</label>
|
|
||||||
<button type="submit" class="btn btn-primary rounded-pill">Create TXT challenge</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row g-3 mt-4 justify-content-center">
|
||||||
{challenge_html}
|
{challenge_html}
|
||||||
{create_form}
|
{create_form}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user