Files
metacrypt/web/templates/issuer_detail.html
Kyle Isom b4dbc088cb Add certificate issuance, CSR signing, and cert listing to web UI
- Add SignCSR RPC to v2 CA proto and regenerate; implement handleSignCSR
  in CA engine and caServer gRPC layer; add SignCSR client method and
  POST /pki/sign-csr web route with result display in pki.html
- Fix issuer detail cert listing: template was using map-style index on
  CertSummary structs; switch to struct field access and populate
  IssuedBy/IssuedAt fields from proto response
- Add certificate detail view (cert_detail.html) with GET /cert/{serial}
  and GET /cert/{serial}/download routes
- Update Makefile proto target to generate both v1 and v2 protos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 13:21:13 -07:00

64 lines
2.3 KiB
HTML

{{define "title"}} - Issuer: {{.IssuerName}}{{end}}
{{define "content"}}
<div class="page-header">
<h2>Issuer: {{.IssuerName}}</h2>
<div class="page-meta">
<a href="/pki">&larr; PKI: {{.MountName}}</a>
&ensp;&middot;&ensp;
<a href="/pki/{{.IssuerName}}" download="{{.IssuerName}}.pem">Download Issuer Cert (PEM)</a>
</div>
</div>
<div class="card">
<div class="card-title">Certificates</div>
<form method="get" action="/pki/issuer/{{.IssuerName}}">
<div class="form-row" style="align-items: flex-end; margin-bottom: 1rem;">
<div class="form-group" style="margin-bottom: 0;">
<label for="name_filter">Filter by name</label>
<input type="text" id="name_filter" name="name" value="{{.NameFilter}}" placeholder="common name contains&hellip;">
</div>
<div class="form-group" style="margin-bottom: 0;">
<label for="sort_by">Sort by</label>
<select id="sort_by" name="sort">
<option value="cn"{{if eq .SortBy "cn"}} selected{{end}}>Common Name</option>
<option value="expiry"{{if eq .SortBy "expiry"}} selected{{end}}>Expiry Date</option>
</select>
</div>
<div style="flex-shrink: 0; padding-bottom: 1px;">
<button type="submit">Apply</button>
</div>
</div>
</form>
{{if .Certs}}
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Common Name</th>
<th>Profile</th>
<th>Serial</th>
<th>Issued By</th>
<th>Issued At</th>
<th>Expires At</th>
</tr>
</thead>
<tbody>
{{range .Certs}}
<tr>
<td><a href="/pki/cert/{{.Serial}}">{{.CommonName}}</a></td>
<td>{{.Profile}}</td>
<td><code>{{.Serial}}</code></td>
<td>{{.IssuedBy}}</td>
<td>{{.IssuedAt}}</td>
<td>{{.ExpiresAt}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{else}}
<p>No certificates found{{if .NameFilter}} matching &ldquo;{{.NameFilter}}&rdquo;{{end}}.</p>
{{end}}
</div>
{{end}}