195 lines
8.3 KiB
PHP
195 lines
8.3 KiB
PHP
<?php
|
|
$server = $server ?? [];
|
|
$ssl = $ssl ?? [];
|
|
$certbotInstalled = $ssl['certbot_installed'] ?? false;
|
|
?>
|
|
|
|
<div class="page-header">
|
|
<div class="page-header-left">
|
|
<div class="back-link">
|
|
<a href="/servers/<?= $server['id'] ?>"><i class="fas fa-arrow-left"></i> Back to Server</a>
|
|
</div>
|
|
<h1 class="page-title"><i class="fas fa-shield-alt"></i> SSL Certificates</h1>
|
|
<p class="page-subtitle"><?= htmlspecialchars($server['name']) ?></p>
|
|
</div>
|
|
<div class="page-header-right">
|
|
<button class="btn btn-secondary" onclick="location.reload()">
|
|
<i class="fas fa-sync-alt"></i> Refresh
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!$certbotInstalled): ?>
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="empty-state">
|
|
<i class="fas fa-shield-alt empty-icon" style="font-size:3rem;opacity:0.4"></i>
|
|
<h3>Certbot is not installed</h3>
|
|
<p>Certbot is required to manage Let's Encrypt SSL certificates on this server.</p>
|
|
<p class="text-muted">Would you like to install it?</p>
|
|
<div class="action-group" style="margin-top:1.5rem;display:flex;gap:0.75rem;justify-content:center">
|
|
<button class="btn btn-primary" onclick="sslAction('install')">
|
|
<i class="fas fa-download"></i> Install Certbot
|
|
</button>
|
|
<button class="btn btn-secondary" onclick="history.back()">
|
|
<i class="fas fa-arrow-left"></i> Go Back
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<?php
|
|
$certs = $ssl['certificates'] ?? [];
|
|
?>
|
|
|
|
<div class="dashboard-grid">
|
|
<div class="dashboard-card">
|
|
<div class="card-header">
|
|
<h2><i class="fas fa-info-circle"></i> Certbot</h2>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="stats-grid" style="grid-template-columns:repeat(2,1fr);gap:0.75rem">
|
|
<div class="stat-card" style="padding:1rem">
|
|
<div class="stat-icon" style="width:40px;height:40px;font-size:1rem;background:var(--success-bg);color:var(--success)">
|
|
<i class="fas fa-check-circle"></i>
|
|
</div>
|
|
<div class="stat-info">
|
|
<span class="stat-value" style="font-size:1rem">Installed</span>
|
|
<span class="stat-label"><?= htmlspecialchars($ssl['version'] ?? '') ?></span>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card" style="padding:1rem">
|
|
<div class="stat-icon" style="width:40px;height:40px;font-size:1rem;background:var(--info-bg);color:var(--info)">
|
|
<i class="fas fa-certificate"></i>
|
|
</div>
|
|
<div class="stat-info">
|
|
<span class="stat-value" style="font-size:1rem"><?= count($certs) ?></span>
|
|
<span class="stat-label">Certificates</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="action-group" style="margin-top:1rem;display:flex;gap:0.5rem;flex-wrap:wrap">
|
|
<button class="btn btn-sm btn-success" onclick="openRequestModal()">
|
|
<i class="fas fa-plus"></i> New Certificate
|
|
</button>
|
|
<button class="btn btn-sm btn-warning" onclick="sslAction('renew')">
|
|
<i class="fas fa-sync-alt"></i> Renew All
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (empty($certs)): ?>
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="empty-state">
|
|
<i class="fas fa-certificate empty-icon" style="opacity:0.3"></i>
|
|
<p>No SSL certificates found.</p>
|
|
<button class="btn btn-primary" onclick="openRequestModal()">
|
|
<i class="fas fa-plus"></i> Request First Certificate
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="dashboard-grid">
|
|
<?php foreach ($certs as $cert): ?>
|
|
<?php
|
|
$expiryTs = strtotime($cert['expiry']);
|
|
$expiryDays = $expiryTs ? floor(($expiryTs - time()) / 86400) : null;
|
|
$expiryClass = 'success';
|
|
if ($expiryDays !== null && $expiryDays < 30) $expiryClass = 'danger';
|
|
elseif ($expiryDays !== null && $expiryDays < 60) $expiryClass = 'warning';
|
|
?>
|
|
<div class="dashboard-card">
|
|
<div class="card-header">
|
|
<h2><i class="fas fa-certificate text-success"></i> <?= htmlspecialchars($cert['name']) ?></h2>
|
|
<span class="badge badge-<?= $expiryClass ?>"><?= $expiryDays !== null ? $expiryDays . ' days' : 'Unknown' ?></span>
|
|
</div>
|
|
<div class="card-body">
|
|
<dl class="details-list">
|
|
<dt>Domains</dt>
|
|
<dd>
|
|
<?php foreach ($cert['domains'] as $domain): ?>
|
|
<code><?= htmlspecialchars($domain) ?></code><?= $domain !== end($cert['domains']) ? ', ' : '' ?>
|
|
<?php endforeach; ?>
|
|
</dd>
|
|
<dt>Expiry</dt>
|
|
<dd><?= htmlspecialchars($cert['expiry'] ?: 'Unknown') ?></dd>
|
|
<?php if (!empty($cert['path'])): ?>
|
|
<dt>Certificate Path</dt>
|
|
<dd><code><?= htmlspecialchars($cert['path']) ?></code></dd>
|
|
<?php endif; ?>
|
|
<?php if (!empty($cert['key_type'])): ?>
|
|
<dt>Key Type</dt>
|
|
<dd><code><?= htmlspecialchars($cert['key_type']) ?></code></dd>
|
|
<?php endif; ?>
|
|
</dl>
|
|
<div class="action-group" style="margin-top:0.75rem;display:flex;gap:0.5rem">
|
|
<button class="btn btn-xs btn-danger" onclick="deleteCert('<?= htmlspecialchars($cert['name']) ?>')">
|
|
<i class="fas fa-trash"></i> Delete
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div id="sslRequestModal" class="modal">
|
|
<div class="modal-dialog" style="max-width:500px">
|
|
<div class="modal-header">
|
|
<h3><i class="fas fa-plus-circle text-success"></i> New SSL Certificate</h3>
|
|
<button class="modal-close" onclick="closeRequestModal()">×</button>
|
|
</div>
|
|
<form id="sslRequestForm" onsubmit="requestCert(event)">
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<label for="sslDomains">Domain(s)</label>
|
|
<input type="text" id="sslDomains" name="domains" class="form-input"
|
|
placeholder="example.com www.example.com" required>
|
|
<small class="form-hint">Separate multiple domains with spaces</small>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="sslEmail">Email (optional)</label>
|
|
<input type="email" id="sslEmail" name="email" class="form-input"
|
|
placeholder="admin@example.com">
|
|
<small class="form-hint">For renewal notices</small>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" onclick="closeRequestModal()">Cancel</button>
|
|
<button type="submit" class="btn btn-success" id="requestCertBtn">
|
|
<i class="fas fa-plus"></i> Request Certificate
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div id="sslResultModal" class="modal">
|
|
<div class="modal-dialog" style="max-width:600px">
|
|
<div class="modal-header">
|
|
<h3 id="sslResultTitle">Result</h3>
|
|
<button class="modal-close" onclick="closeSslResultModal()">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p id="sslResultMessage"></p>
|
|
<div id="sslResultOutput" class="nginx-config-viewer nginx-test-output" style="display:none;margin-top:0.75rem">
|
|
<pre><code id="sslResultOutputText"></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-secondary" onclick="closeSslResultModal()">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const serverId = <?= $server['id'] ?>;
|
|
</script>
|
|
<script src="/assets/js/server-ssl.js?v=<?= asset_version() ?>"></script>
|