Security Policy (SECURITY.md) Template Generator
Manage Policy Sections
Use this area to customize the content for each core section of your SECURITY.md file.
SECURITY.md Preview (Markdown)
Click "Generate Policy" to preview your final Markdown document.
')
.replace(/\n/g, '
')
.replace(/
<\/p>/g, ''); pdfDownloadBtn.disabled = false; switchTab(2); // Switch to review tab }; const downloadPDF = () => { const metaData = getMetaFormData(); const jsPDF = window.jspdf.jsPDF; const doc = new jsPDF('p', 'pt', 'a4'); let currentY = 40; const margin = 40; const pageWidth = doc.internal.pageSize.width; const maxWidth = pageWidth - (margin * 2); const checkPageBreak = (spaceNeeded) => { if (currentY + spaceNeeded > doc.internal.pageSize.height - margin) { doc.addPage(); currentY = margin; } }; const addText = (text, size = 10, style = 'normal', indent = 0, color = 0) => { doc.setFontSize(size); doc.setFont('Helvetica', style); doc.setTextColor(color); const lines = doc.splitTextToSize(text, maxWidth - indent); checkPageBreak(lines.length * (size * 1.2)); doc.text(lines, margin + indent, currentY); currentY += (lines.length * (size * 1.2)); doc.setTextColor(0); }; const addSectionHeader = (title) => { checkPageBreak(25); doc.setFontSize(18); doc.setFont('Helvetica', 'bold'); doc.setTextColor(46, 139, 87); doc.text(title, margin, currentY); currentY += 12; doc.setLineWidth(0.5); doc.setDrawColor(200); doc.line(margin, currentY, pageWidth - margin, currentY); currentY += 15; doc.setTextColor(0); }; // --- PDF Content --- // Title Block doc.setFontSize(24); doc.setFont('Helvetica', 'bold'); doc.setTextColor(46, 139, 87); doc.text(`${metaData.policy_project_name} Security Policy`, pageWidth / 2, currentY, { align: 'center' }); currentY += 18; // Metadata Table const metaBody = [ ["Status:", metaData.policy_status], ["Last Updated:", metaData.policy_date], ["Scope:", metaData.policy_scope] ]; doc.autoTable({ startY: currentY, head: [['Metadata', 'Details']], body: metaBody, theme: 'plain', styles: { fontSize: 9, font: 'Helvetica' }, headStyles: { fillColor: [240, 240, 240], textColor: [0], fontStyle: 'bold' }, columnStyles: { 0: { fontStyle: 'bold', cellWidth: 100 } } }); currentY = doc.autoTable.previous.finalY + 20; // Policy Sections policySections.forEach(section => { let content = section.content; // Replace template placeholders with form data content = content.replace(/\[PROJECT_NAME\]/g, metaData.policy_project_name); content = content.replace(/\[REPORTING_METHOD\]/g, metaData.reporting_method); content = content.replace(/\[REPORTING_EMAIL\]/g, metaData.reporting_email); content = content.replace(/\[PGP_KEY_URL\]/g, metaData.pgp_key_url); content = content.replace(/\[DISCLOSURE_POLICY\]/g, metaData.disclosure_policy); content = content.replace(/\[RESPONSE_TIMELINE\]/g, metaData.response_timeline); addSectionHeader(section.title); addText(content, 11, 'normal', 5); }); // Footer checkPageBreak(15); currentY = doc.internal.pageSize.height - 30; doc.setFontSize(8); doc.setFont('Helvetica', 'italic'); doc.setTextColor(150); doc.text("This policy is generated for internal use and external disclosure.", pageWidth / 2, currentY, { align: 'center' }); doc.save(`${metaData.policy_project_name.replace(/\s/g, '_')}_SECURITY_Policy.pdf`); }; // --- Tab Navigation --- const switchTab = (tabIndex) => { tabs.forEach((tab, index) => { tab.classList.toggle('active', index === tabIndex); contents[index].classList.toggle('active', index === tabIndex); }); currentTab = tabIndex; updateNavButtons(); if (tabIndex === 2) { generatePolicy(); } } const updateNavButtons = () => { prevBtn.disabled = currentTab === 0; nextBtn.disabled = currentTab === tabs.length - 1; } tabs.forEach((tab, index) => { tab.addEventListener('click', () => { const tabNode = tab.closest('.security-tab-button'); const newIndex = Array.from(tabNode.parentNode.children).indexOf(tabNode); switchTab(newIndex); }); }); nextBtn.addEventListener('click', () => { if (currentTab < tabs.length - 1) switchTab(currentTab + 1); }); prevBtn.addEventListener('click', () => { if (currentTab > 0) switchTab(currentTab - 1); }); // --- Event Listeners and Initial Load --- generatePolicyBtn.addEventListener('click', generatePolicy); pdfDownloadBtn.addEventListener('click', downloadPDF); // Initial Setup setInitialDate(); renderPolicySections(); updateNavButtons(); });
