- checker.js: checkSecurityHeaders() graded A+-F, checkSSL() via SSL Labs API - Both run in parallel with sitespeed.io to minimise wait time - DB: auto-migrate headers_json + ssl_json columns - Layout: coach scores + CWV side-by-side, headers + SSL below - Scorecard + CWV made compact Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
22 lines
1.4 KiB
Plaintext
22 lines
1.4 KiB
Plaintext
- const hd = job.headers_json ? JSON.parse(job.headers_json) : null
|
|
- function hdColor(g) { return !g ? 'bg-gray-100 text-gray-400' : g === 'A+' ? 'bg-green-100 text-green-700' : g === 'A' ? 'bg-green-100 text-green-700' : g === 'B' ? 'bg-yellow-100 text-yellow-700' : g === 'C' ? 'bg-orange-100 text-orange-700' : 'bg-red-100 text-red-700'; }
|
|
|
|
div(class='bg-white border border-gray-200 rounded-xl p-5')
|
|
h2(class='text-base font-semibold mb-3') Security Headers
|
|
if hd
|
|
div(class='flex items-start gap-5 flex-wrap')
|
|
div(class='flex flex-col items-center gap-1')
|
|
div(class=`score-circle w-14 h-14 text-lg ${hdColor(hd.grade)}`)= hd.grade
|
|
span(class='text-xs text-gray-500') Grade
|
|
span(class='text-xs text-gray-400 mt-0.5')= hd.headers.filter(h=>h.present).length + '/' + hd.headers.length
|
|
div(class='grid grid-cols-1 sm:grid-cols-2 gap-1 flex-1')
|
|
each h in hd.headers
|
|
div(class=`flex items-center justify-between rounded px-3 py-1.5 text-xs ${h.present ? 'bg-green-50' : h.important ? 'bg-red-50' : 'bg-gray-50'}`)
|
|
span(class='font-mono')= h.label
|
|
if h.present
|
|
span(class='text-green-600 font-bold ml-2') ✓
|
|
else
|
|
span(class=`font-bold ml-2 ${h.important ? 'text-red-500' : 'text-gray-400'}`) ✗
|
|
else
|
|
p(class='text-sm text-gray-400 italic') Not available
|