Skip to main content

max / makenotwork

Fix custom domain form: accept Form instead of Json The add_domain endpoint expected JSON but the HTMX form sends form-encoded data, causing a 415 error. Also fix verify_domain to return HTML fragments instead of raw JSON for HTMX targets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-11 01:11 UTC
Commit: ed75ccf8ed220ea0a9327b2bb03927e63f4953f7
Parent: cb328fa
2 files changed, +15 insertions, -29 deletions
@@ -3445,7 +3445,7 @@ dependencies = [
3445 3445
3446 3446 [[package]]
3447 3447 name = "makenotwork"
3448 - version = "0.5.13"
3448 + version = "0.5.14"
3449 3449 dependencies = [
3450 3450 "anyhow",
3451 3451 "argon2",
@@ -5,7 +5,7 @@ use axum::{
5 5 response::IntoResponse,
6 6 Form, Json,
7 7 };
8 - use serde::{Deserialize, Serialize};
8 + use serde::Deserialize;
9 9 use serde_json::json;
10 10
11 11 use crate::{
@@ -20,21 +20,13 @@ pub(super) struct AddDomainRequest {
20 20 domain: String,
21 21 }
22 22
23 - #[derive(Serialize)]
24 - struct DomainResponse {
25 - id: CustomDomainId,
26 - domain: String,
27 - verified: bool,
28 - verification_token: String,
29 - instructions: String,
30 - }
31 23
32 24 /// POST /api/domains — add a custom domain.
33 25 #[tracing::instrument(skip_all, name = "api::domains::add")]
34 26 pub(super) async fn add_domain(
35 27 State(state): State<AppState>,
36 28 AuthUser(session_user): AuthUser,
37 - Json(req): Json<AddDomainRequest>,
29 + Form(req): Form<AddDomainRequest>,
38 30 ) -> Result<impl IntoResponse> {
39 31 session_user.check_not_sandbox()?;
40 32 let domain = normalize_domain(&req.domain)?;
@@ -42,22 +34,19 @@ pub(super) async fn add_domain(
42 34
43 35 let verification_token = generate_verification_token();
44 36
45 - let row =
37 + let _row =
46 38 db::custom_domains::create_custom_domain(&state.db, session_user.id, &domain, &verification_token)
47 39 .await?;
48 40
49 41 let instructions = format!(
50 - "Add a DNS TXT record: _mnw-verify.{} with value {}",
42 + "Add a DNS TXT record: <code>_mnw-verify.{}</code> with value <code>{}</code>",
51 43 domain, verification_token
52 44 );
53 45
54 - Ok(Json(DomainResponse {
55 - id: row.id,
56 - domain: row.domain,
57 - verified: row.verified,
58 - verification_token: row.verification_token,
59 - instructions,
60 - }))
46 + Ok(axum::response::Html(format!(
47 + "<p class=\"success\">{}</p>",
48 + instructions
49 + )))
61 50 }
62 51
63 52 #[derive(Deserialize)]
@@ -82,7 +71,7 @@ pub(super) async fn verify_domain(
82 71 }
83 72
84 73 if cd.verified {
85 - return Ok(Json(json!({"verified": true, "message": "Domain already verified."})));
74 + return Ok(axum::response::Html("<p class=\"success\">Domain already verified.</p>".to_string()));
86 75 }
87 76
88 77 // Query DNS via Cloudflare DNS-over-HTTPS
@@ -94,13 +83,10 @@ pub(super) async fn verify_domain(
94 83 .any(|txt| txt.trim() == cd.verification_token);
95 84
96 85 if !matched {
97 - return Ok(Json(json!({
98 - "verified": false,
99 - "message": format!(
100 - "TXT record not found. Add _mnw-verify.{} TXT {} and try again.",
101 - cd.domain, cd.verification_token
102 - )
103 - })));
86 + return Ok(axum::response::Html(format!(
87 + "<p class=\"error\">TXT record not found. Add <code>_mnw-verify.{}</code> TXT <code>{}</code> and try again.</p>",
88 + cd.domain, cd.verification_token
89 + )));
104 90 }
105 91
106 92 // Mark verified in DB and update cache
@@ -109,7 +95,7 @@ pub(super) async fn verify_domain(
109 95 .domain_cache
110 96 .insert(cd.domain.clone(), session_user.id);
111 97
112 - Ok(Json(json!({"verified": true, "message": "Domain verified successfully."})))
98 + Ok(axum::response::Html("<p class=\"success\">Domain verified successfully. Reload to see changes.</p>".to_string()))
113 99 }
114 100
115 101 /// DELETE /api/domains/{id} — remove a custom domain.