- Extend commands.yml.example with caddy_list_certs (sh loop over /data/caddy/certificates/*/*.crt using openssl) - Add lib/parse-caddy.ts: parseCertList() parses CERTFILE/CERTEND delimited openssl output - Add shiki ^1.29.2 dependency for server-side Caddyfile syntax highlighting Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
export interface CertInfo {
|
|
domain: string
|
|
subject: string
|
|
issuer: string
|
|
issuerCN: string
|
|
notBefore: string
|
|
notAfter: string
|
|
expiringWarning: boolean
|
|
expired: boolean
|
|
}
|
|
|
|
export function parseCertList(output: string): CertInfo[] {
|
|
const certs: CertInfo[] = []
|
|
const blocks = output.split('CERTEND')
|
|
|
|
for (const block of blocks) {
|
|
const fileMatch = block.match(/CERTFILE:(.+)/)
|
|
if (!fileMatch) continue
|
|
|
|
const filePath = fileMatch[1].trim()
|
|
const domain = filePath.split('/').filter(Boolean).pop()?.replace(/\.crt$/, '') ?? ''
|
|
|
|
let subject = ''
|
|
let issuer = ''
|
|
let notBefore = ''
|
|
let notAfter = ''
|
|
|
|
for (const line of block.split('\n')) {
|
|
const subjectMatch = line.match(/^subject=(.+)/)
|
|
if (subjectMatch) subject = subjectMatch[1].trim()
|
|
|
|
const issuerMatch = line.match(/^issuer=(.+)/)
|
|
if (issuerMatch) issuer = issuerMatch[1].trim()
|
|
|
|
const notBeforeMatch = line.match(/^notBefore=(.+)/)
|
|
if (notBeforeMatch) notBefore = notBeforeMatch[1].trim()
|
|
|
|
const notAfterMatch = line.match(/^notAfter=(.+)/)
|
|
if (notAfterMatch) notAfter = notAfterMatch[1].trim()
|
|
}
|
|
|
|
const issuerCN = issuer.match(/CN\s*=\s*([^,]+)/)?.[1]?.trim() ?? issuer
|
|
|
|
const now = Date.now()
|
|
const notAfterDate = notAfter ? new Date(notAfter) : null
|
|
const notAfterMs = notAfterDate?.getTime() ?? Infinity
|
|
const expiringWarning = notAfterMs - now < 30 * 24 * 60 * 60 * 1000
|
|
const expired = notAfterMs < now
|
|
|
|
certs.push({ domain, subject, issuer, issuerCN, notBefore, notAfter, expiringWarning, expired })
|
|
}
|
|
|
|
return certs
|
|
}
|