Commit dbd18f08cd
dbd18f08cd5999c73ffbedec7998e9290f7ba7fe
parent: 73c8e291f7
Verified · cmc ci/build: success
cmc <hello@cleberg.net> · 2026-08-26T05:20:37Z
web: drop the key comment column
SSH keys are stored in wire format, which carries no comment — reading
one out of the blob printed binary noise next to each fingerprint.
Ref #35
e2e/accountweb_test.go
+5
| @@ -38,6 +38,11 @@ func TestAccountSettingsWeb(t *testing.T) { |
| 38 | 38 | if !strings.Contains(body, "SHA256:") { |
| 39 | 39 | t.Error("no SSH key fingerprint listed") |
| 40 | 40 | } |
| 41 | // Keys are stored in wire format, which holds no comment; anything |
| 42 | // pulled out of it and printed would be binary noise. |
| 43 | if strings.Contains(body, "\ufffd") { |
| 44 | t.Error("key row is rendering raw blob bytes") |
| 45 | } |
| 41 | 46 | if !strings.Contains(body, "alice@example.test") || !strings.Contains(body, "verified") { |
| 42 | 47 | t.Error("verified address not shown") |
| 43 | 48 | } |
e2e/facts_test.go
+3 −3
| @@ -47,9 +47,9 @@ func TestRepoFacts(t *testing.T) { |
| 47 | 47 | "<strong>2</strong> commit", // both commits counted |
| 48 | 48 | "<strong>1</strong> branch", |
| 49 | 49 | "<strong>1</strong> tag", |
| 50 | | "0BSD", // license detected and surfaced |
| 51 | | "Go", // language census |
| 52 | | "Shell", // and it is not single-language |
| 50 | "0BSD", // license detected and surfaced |
| 51 | "Go", // language census |
| 52 | "Shell", // and it is not single-language |
| 53 | 53 | "2 contributors", |
| 54 | 54 | } { |
| 55 | 55 | if !strings.Contains(body, want) { |
internal/httpd/account.go
+1 −15
| @@ -15,7 +15,6 @@ type accountKey struct { |
| 15 | 15 | Fingerprint string |
| 16 | 16 | Algo string |
| 17 | 17 | Scope string |
| 18 | | Comment string |
| 19 | 18 | } |
| 20 | 19 | |
| 21 | 20 | type accountPGP struct { |
| @@ -31,10 +30,7 @@ func (s *Server) accountForm(w http.ResponseWriter, r *http.Request, u store.Use |
| 31 | 30 | var keys []accountKey |
| 32 | 31 | if list, err := s.st.ListSSHKeys(u.ID); err == nil { |
| 33 | 32 | for _, k := range list { |
| 34 | | keys = append(keys, accountKey{ |
| 35 | | Fingerprint: k.Fingerprint, Algo: k.Algo, Scope: k.Scope, |
| 36 | | Comment: keyComment(k.Blob), |
| 37 | | }) |
| 33 | keys = append(keys, accountKey{Fingerprint: k.Fingerprint, Algo: k.Algo, Scope: k.Scope}) |
| 38 | 34 | } |
| 39 | 35 | } |
| 40 | 36 | var pgp []accountPGP |
| @@ -62,16 +58,6 @@ func (s *Server) accountForm(w http.ResponseWriter, r *http.Request, u store.Use |
| 62 | 58 | r.URL.Query().Get("e"), r.URL.Query().Get("m")}) |
| 63 | 59 | } |
| 64 | 60 | |
| 65 | | // keyComment pulls the trailing comment off an authorized_keys blob, which |
| 66 | | // is how people tell their own keys apart. |
| 67 | | func keyComment(blob []byte) string { |
| 68 | | f := strings.Fields(string(blob)) |
| 69 | | if len(f) < 3 { |
| 70 | | return "" |
| 71 | | } |
| 72 | | return strings.Join(f[2:], " ") |
| 73 | | } |
| 74 | | |
| 75 | 61 | // accountSubmit routes the account forms to their commands. Everything |
| 76 | 62 | // here is a public key or an address — no secret is accepted over the web. |
| 77 | 63 | func (s *Server) accountSubmit(w http.ResponseWriter, r *http.Request, u store.User) { |
internal/web/templates/account.html
+1 −1
| @@ -11,7 +11,7 @@ a CI checkout wants.</p> |
| 11 | 11 | {{if .Keys}}<div class="tablewrap"><table class="keys"> |
| 12 | 12 | <tr class="cols"><th scope="col">fingerprint</th><th scope="col">type</th><th scope="col">scope</th><th scope="col"></th></tr> |
| 13 | 13 | {{range .Keys}}<tr> |
| 14 | | <td class="mono">{{.Fingerprint}}{{with .Comment}}<br><span class="muted">{{.}}</span>{{end}}</td> |
| 14 | <td class="mono">{{.Fingerprint}}</td> |
| 15 | 15 | <td>{{.Algo}}</td> |
| 16 | 16 | <td>{{.Scope}}</td> |
| 17 | 17 | <td class="act"><form method="post" action="/settings"><input type="hidden" name="field" value="key-remove"><input type="hidden" name="fingerprint" value="{{.Fingerprint}}"><button type="submit" class="linklike">Remove</button></form></td> |