Skip to main content

max / makenotwork

Point the described tab's Remove at a route that exists Found starting S4. Both buttons on the described SSH-keys tab posted to a `/delete` suffix that appears nowhere in the route table: the real endpoints are DELETE /api/users/me/ssh-keys/{id} and the git-tokens twin. The paths were invented because a described write could only be a POST, so the tab rendered correctly and its destructive actions answered 404. The acceptance test for S3 was only ever visual. quasi@bfe40fe lets an action name its verb, so both now address the route the server answers. CSRF rides along unchanged: the core module attaches the token on htmx:configRequest for every request on the page, which is how the Askama version was covered too.
Author: Max Johnson <me@maxj.phd> · 2026-08-11 00:05 UTC
Signed with PGP, not checked
Commit: e9e8b0d266bf4cdfcdb8bc7f7af56112e8785272
Parent: 9021a9d
1 file changed, +9 insertions, -4 deletions
@@ -185,7 +185,12 @@
185 185 Cell::new(format!("Added {}", key.added)),
186 186 Cell::acts([Act::new(
187 187 "Remove",
188 - Action::post(format!("/api/users/me/ssh-keys/{}/delete", key.id)),
188 + // The route the server actually answers. This posted to
189 + // a `/delete` path invented because a described write
190 + // could only be a POST, and that path was registered
191 + // nowhere, so the button rendered and answered 404.
192 + // `61e1b069` closed the gap; quasi@bfe40fe.
193 + Action::delete(format!("/api/users/me/ssh-keys/{}", key.id)),
189 194 )
190 195 // The template asked with hx-confirm. Said here, a terminal
191 196 // host asks in its own way and no host can forget to ask.
@@ -268,7 +273,7 @@
268 273 Cell::new(token.last_used.clone()),
269 274 Cell::acts([Act::new(
270 275 "Revoke",
271 - Action::post(format!("/api/users/me/git-tokens/{}/delete", token.id)),
276 + Action::delete(format!("/api/users/me/git-tokens/{}", token.id)),
272 277 )
273 278 .confirm("Revoke this token?")
274 279 .tone(layout::Tone::Danger)]),
@@ -376,8 +381,8 @@
376 381 assert_eq!(html.matches("hx-confirm").count(), 2, "both ask: {html}");
377 382 // The addresses are per key rather than one shared endpoint, which is
378 383 // the mistake a loop over rows makes when the id is read outside it.
379 - assert!(html.contains("/api/users/me/ssh-keys/k1/delete"));
380 - assert!(html.contains("/api/users/me/ssh-keys/k2/delete"));
384 + assert!(html.contains("hx-delete=\"/api/users/me/ssh-keys/k1\""));
385 + assert!(html.contains("hx-delete=\"/api/users/me/ssh-keys/k2\""));
381 386 }
382 387
383 388 #[test]