Simplify DDNS flow and polish UI

This commit is contained in:
StasonJatham committed 2026-05-21 14:18:39 +02:00
1 parent 5beee0e5c6
commit 5a90bd9d87
42 files changed
+587 -1418

No files matched your search

+1 -73
View File
@@ -1,24 +1,17 @@
from __future__ import annotations
import sqlite3
from fastapi import APIRouter, HTTPException, Request, Response, status
from starlette.concurrency import run_in_threadpool
from ..ddns_dns import DnsProviderError
from ..ddns_service import BadIpError, normalize_domain
from ..ddns_service import BadIpError
from ..dependencies import ServiceDep, StoreDep
from ..schemas import (
CustomHostnameRequest,
DomainChallengeRequest,
DomainChallengeResponse,
ErrorResponse,
HostnameCredentials,
MagicHostnameRequest,
ManagedRecord,
RouterUpdateResponse,
VerifyDomainRequest,
VerifyDomainResponse,
_credentials_response,
_managed_record,
)
@@ -75,71 +68,6 @@ async def delete_managed_hostname(management_slug: ManagementSlugPath, store: St
return Response(status_code=status.HTTP_204_NO_CONTENT)
@router.post(
"/domains/challenges",
response_model=DomainChallengeResponse,
status_code=status.HTTP_201_CREATED,
summary="Create a DNS TXT domain verification challenge",
tags=["domains"],
responses={400: {"model": ErrorResponse}},
)
async def create_domain_challenge(payload: DomainChallengeRequest, service: ServiceDep) -> DomainChallengeResponse:
domain = normalize_domain(payload.domain)
try:
challenge = await run_in_threadpool(service.create_domain_challenge, domain)
except sqlite3.IntegrityError as exc:
raise HTTPException(status_code=409, detail="domain is already verified") from exc
return DomainChallengeResponse(
domain=domain,
txt_name=service.verification_name(domain),
txt_value=challenge["token"],
claim_secret=challenge["claim_secret"],
)
@router.post(
"/domains/verify",
response_model=VerifyDomainResponse,
summary="Verify a domain TXT challenge",
tags=["domains"],
responses={404: {"model": ErrorResponse}},
)
async def verify_domain(payload: VerifyDomainRequest, service: ServiceDep) -> VerifyDomainResponse:
domain = normalize_domain(payload.domain)
found, _challenge = await run_in_threadpool(service.verify_domain, domain, payload.claim_secret)
if not found:
return VerifyDomainResponse(
domain=domain,
verified=False,
message="TXT record not found yet",
claim_secret=payload.claim_secret,
)
return VerifyDomainResponse(
domain=domain,
verified=True,
message="Domain verified",
claim_secret=payload.claim_secret,
)
@router.post(
"/hostnames/custom",
response_model=HostnameCredentials,
status_code=status.HTTP_201_CREATED,
summary="Create a hostname for a verified domain",
tags=["hostnames"],
responses={400: {"model": ErrorResponse}, 403: {"model": ErrorResponse}, 409: {"model": ErrorResponse}},
)
async def create_custom_hostname(payload: CustomHostnameRequest, service: ServiceDep) -> HostnameCredentials:
account = await run_in_threadpool(
service.create_custom_account,
payload.hostname,
payload.claim_secret,
payload.username,
)
return _credentials_response(service, account)
@router.get(
"/updates/{update_slug}",
response_model=RouterUpdateResponse,