tirbofish/kitgit · diff
feat: polish signed commit verification badges
Type: SSH
SSH Key Fingerprint:
Verified
SgQHY4vUORbJC3ZtdixCl62ek/4QGh/iG2FRSyjfGPc
@@ -2491,6 +2491,7 @@ async fn commit_view( c: git::CommitInfo, extracted: Option<(String, Vec<u8>)>, ) -> CommitView { + let signed = extracted.is_some(); let verification = match extracted { Some((sig, payload)) => { git::verify_commit_signature( @@ -2525,6 +2526,7 @@ async fn commit_view( author: c.author, email: c.email, time: c.time, + signed, verified, verify_kind, verify_fingerprint, @@ -65,6 +65,8 @@ pub struct CommitView { pub author: String, pub email: String, pub time: i64, + /// True when a signature blob was present on the commit (SSH or GPG). + pub signed: bool, pub verified: bool, pub verify_kind: String, pub verify_fingerprint: String, @@ -72,6 +74,16 @@ pub struct CommitView { pub verified_at: String, } +impl CommitView { + pub fn verify_kind_label(&self) -> &'static str { + match self.verify_kind.as_str() { + "gpg" => "GPG", + "ssh" => "SSH", + _ => "Unknown", + } + } +} + pub struct CollaboratorView { pub user: User, pub role: String, @@ -1467,6 +1467,20 @@ html.kg-dark .kg-codeview .punctuation { color: #b0b0b0; } cursor: pointer; } +.kg-badge--unverified { + color: var(--kg-muted); + border-color: var(--kg-line-strong); + background: transparent; + text-transform: none; + letter-spacing: 0.02em; + font-weight: 600; + cursor: default; +} + +.kg-verify .kg-badge--unverified { + cursor: pointer; +} + .kg-verify { position: relative; display: inline-block; @@ -1494,6 +1508,12 @@ html.kg-dark .kg-codeview .punctuation { color: #b0b0b0; } box-shadow: 0 8px 24px color-mix(in srgb, var(--kg-fg) 12%, transparent); } +.kg-verify__row { + margin: 0 0 0.35rem; + font-size: 0.8125rem; + line-height: 1.4; +} + .kg-verify__fp { margin: 0 0 0.35rem; font-size: 0.8125rem; @@ -1505,6 +1525,29 @@ html.kg-dark .kg-codeview .punctuation { color: #b0b0b0; } font-size: 0.75rem; } +.kg-verify__panel a { + color: inherit; + text-decoration: underline; +} + +.kg-signing-hint { + margin: 1rem 0 0; + padding: var(--kg-space-3); + border: 1px dashed var(--kg-line-strong); + background: color-mix(in srgb, var(--kg-fg) 3%, transparent); + font-size: 0.875rem; + line-height: 1.5; +} + +.kg-signing-hint pre { + margin: 0.5rem 0 0; + padding: var(--kg-space-2); + overflow-x: auto; + font-size: 0.75rem; + background: var(--kg-bg); + border: 1px solid var(--kg-line); +} + .kg-key-row { align-items: flex-start; } @@ -17,7 +17,7 @@ {% endif %} <span class="kg-kicker" style="margin-top:1.5rem">SSH keys</span> - <p class="kg-muted">Authentication keys let you push/pull over SSH. Signing keys verify signed commits.</p> + <p class="kg-muted">Authentication keys let you push/pull over SSH. Signing keys verify signed commits on kitgit (Verified badge).</p> {% if !keys.is_empty() %} <ul class="kg-list"> {% for key in keys %} @@ -70,6 +70,14 @@ </div> </form> + <div class="kg-signing-hint"> + <strong>Sign commits with SSH</strong> + <p class="kg-muted" style="margin:0.35rem 0 0">Add the public key above with usage <em>Signing</em> or <em>Authentication & Signing</em>, then configure git locally. Author email must match a verified email on your account.</p> + <pre>git config --global gpg.format ssh +git config --global user.signingkey ~/.ssh/id_ed25519.pub +git config --global commit.gpgsign true</pre> + </div> + <span class="kg-kicker" style="margin-top:2.5rem">GPG keys</span> <p class="kg-muted">Used for commit verification. Vigilant mode flags unsigned commits on your profile.</p> {% if !gpg_keys.is_empty() %} @@ -104,5 +112,12 @@ <button class="kg-btn" type="submit">add</button> </div> </form> + + <div class="kg-signing-hint"> + <strong>Sign commits with GPG</strong> + <p class="kg-muted" style="margin:0.35rem 0 0">Paste your public key above, then point git at the key id. Author email must match a verified email on your account.</p> + <pre>git config --global user.signingkey YOUR_KEY_ID +git config --global commit.gpgsign true</pre> + </div> </section> {% endblock %} @@ -12,18 +12,8 @@ {{ c.short_id }} </a> <a class="kg-branchbar__msg" href="/{{ owner.username }}/{{ repo.name }}/commit/{{ c.id }}" title="View commit">{{ c.message }}</a> - {% if c.verified %} - <details class="kg-verify"> - <summary class="kg-badge kg-badge--verified">Verified</summary> - <div class="kg-verify__panel" role="dialog" aria-label="Commit signature"> - <p class="kg-verify__fp"> - <strong>{{ c.verify_fingerprint_label }}:</strong> - <code>{{ c.verify_fingerprint }}</code> - </p> - <p class="kg-meta">Verified on {{ c.verified_at }}</p> - </div> - </details> - {% endif %} + {% let show_unverified = false %} + {% include "partials/verified_badge.html" %} </div> {% endif %} </div> @@ -1,12 +1,24 @@ -{% if let Some(v) = verification %} +{# Expects CommitView as `c`. Optional: `show_unverified` (bool) — show Unverified for unsigned too. #} +{% if c.verified %} <details class="kg-verify"> <summary class="kg-badge kg-badge--verified">Verified</summary> <div class="kg-verify__panel" role="dialog" aria-label="Commit signature"> + <p class="kg-verify__row"><strong>Type:</strong> {{ c.verify_kind_label() }}</p> <p class="kg-verify__fp"> - <strong>{{ v.fingerprint_label() }}:</strong> - <code>{{ v.fingerprint }}</code> + <strong>{{ c.verify_fingerprint_label }}:</strong> + <code>{{ c.verify_fingerprint }}</code> </p> - <p class="kg-meta">Verified on {{ v.verified_at }}</p> + <p class="kg-meta">Verified on {{ c.verified_at }}</p> </div> </details> +{% else if c.signed %} +<details class="kg-verify"> + <summary class="kg-badge kg-badge--unverified">Unverified</summary> + <div class="kg-verify__panel" role="dialog" aria-label="Commit signature"> + <p class="kg-verify__row">Signature present but could not be verified.</p> + <p class="kg-meta">Add a matching signing SSH or GPG key under <a href="/settings/keys">Settings → SSH / GPG</a>. The commit author email must match a verified email on that account.</p> + </div> +</details> +{% else if show_unverified %} +<span class="kg-badge kg-badge--unverified" title="Commit is not signed">Unverified</span> {% endif %} @@ -98,18 +98,8 @@ <span> <a href="/{{ owner.username }}/{{ repo.name }}/commits" title="View commits"><code>{{ c.short_id }}</code></a> <a href="/{{ owner.username }}/{{ repo.name }}/commit/{{ c.id }}">{{ c.message }}</a> - {% if c.verified %} - <details class="kg-verify"> - <summary class="kg-badge kg-badge--verified">Verified</summary> - <div class="kg-verify__panel" role="dialog" aria-label="Commit signature"> - <p class="kg-verify__fp"> - <strong>{{ c.verify_fingerprint_label }}:</strong> - <code>{{ c.verify_fingerprint }}</code> - </p> - <p class="kg-meta">Verified on {{ c.verified_at }}</p> - </div> - </details> - {% endif %} + {% let show_unverified = false %} + {% include "partials/verified_badge.html" %} </span> <span class="kg-meta">{{ c.author }}</span> </li> @@ -15,18 +15,9 @@ <p><code>{{ commit.id }}</code></p> <p class="kg-title"> {{ message_html|safe }} - {% if commit.verified %} - <details class="kg-verify"> - <summary class="kg-badge kg-badge--verified">Verified</summary> - <div class="kg-verify__panel" role="dialog" aria-label="Commit signature"> - <p class="kg-verify__fp"> - <strong>{{ commit.verify_fingerprint_label }}:</strong> - <code>{{ commit.verify_fingerprint }}</code> - </p> - <p class="kg-meta">Verified on {{ commit.verified_at }}</p> - </div> - </details> - {% endif %} + {% let c = commit %} + {% let show_unverified = true %} + {% include "partials/verified_badge.html" %} </p> <p class="kg-meta">{{ commit.author }} <{{ commit.email }}> · {{ commit.time }}</p> @@ -31,18 +31,8 @@ <code>{{ c.short_id }}</code> </a> <a href="/{{ owner.username }}/{{ repo.name }}/commit/{{ c.id }}">{{ c.message }}</a> - {% if c.verified %} - <details class="kg-verify"> - <summary class="kg-badge kg-badge--verified">Verified</summary> - <div class="kg-verify__panel" role="dialog" aria-label="Commit signature"> - <p class="kg-verify__fp"> - <strong>{{ c.verify_fingerprint_label }}:</strong> - <code>{{ c.verify_fingerprint }}</code> - </p> - <p class="kg-meta">Verified on {{ c.verified_at }}</p> - </div> - </details> - {% endif %} + {% let show_unverified = false %} + {% include "partials/verified_badge.html" %} <span class="kg-muted"> — {{ c.author }}</span> </span> <span class="kg-meta">{{ c.time }}</span> @@ -21,6 +21,9 @@ </p> <p class="kg-title"> <a href="/{{ owner.username }}/{{ repo.name }}/commit/{{ commit.id }}">{{ commit.message }}</a> + {% let c = commit %} + {% let show_unverified = true %} + {% include "partials/verified_badge.html" %} </p> {{ diff_html|safe }}