import { useEffect, useState } from 'react' import Modal from 'react-bootstrap/Modal' import { apiRequest } from '../api/client' import { PageHeader, AdminButton, AdminAlert } from '../components/admin' interface Domain { id: number name: string port: string site_id: number site_name: string site_path: string } interface Certificate { name: string path: string } interface SslDiagnostics { vhost_dir: string include_snippet: string vhosts: { file: string; has_listen_80: boolean; has_listen_443: boolean; has_ssl_directives: boolean }[] any_vhost_listen_ssl: boolean nginx_effective_listen_443: boolean panel_vhost_path_in_nginx_t: boolean nginx_t_probe_errors: string[] hints: string[] } export function DomainsPage() { const [domains, setDomains] = useState([]) const [certificates, setCertificates] = useState([]) const [diag, setDiag] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [requesting, setRequesting] = useState(null) const [requestDomain, setRequestDomain] = useState(null) const [requestEmail, setRequestEmail] = useState('') const load = () => { setLoading(true) Promise.all([ apiRequest('/ssl/domains'), apiRequest<{ certificates: Certificate[] }>('/ssl/certificates'), ]) .then(([d, c]) => { setDomains(d) setCertificates(c.certificates || []) }) .catch((err) => setError(err.message)) .finally(() => setLoading(false)) } useEffect(() => { load() }, []) const handleRequestCert = (e: React.FormEvent) => { e.preventDefault() if (!requestDomain) return setRequesting(requestDomain.name) apiRequest<{ status: boolean }>('/ssl/request', { method: 'POST', body: JSON.stringify({ domain: requestDomain.name, webroot: requestDomain.site_path, email: requestEmail, }), }) .then(() => { setRequestDomain(null) load() }) .catch((err) => setError(err.message)) .finally(() => setRequesting(null)) } const hasCert = (domain: string) => certificates.some((c) => c.name === domain || c.name.startsWith(domain + ' ')) if (loading) { return ( <>

Loading…

) } return ( <> {error ? {error} : null}
Request Let's Encrypt certificates for your site domains. Requires certbot and nginx configured for the domain.
{diag ? (
HTTPS / nginx check
{diag.hints.length ? (
    {diag.hints.map((h, i) => (
  • {h}
  • ))}
) : null}
Include YakPanel vhosts inside the http block of the nginx process that serves your sites:
{diag.include_snippet} {diag.vhosts.length > 0 ? (
Panel configs scanned:{' '} {diag.vhosts.map((v) => `${v.file}${v.has_listen_443 && v.has_ssl_directives ? ' (HTTPS block)' : ''}`).join(', ')}
) : null} {diag.nginx_t_probe_errors.length > 0 ? (
nginx -T probe: {diag.nginx_t_probe_errors.join(' | ')}
) : null}
) : null}
Domains (from sites)
{domains.length === 0 ? (
No domains. Add a site first.
) : ( domains.map((d) => (
{d.name} {d.port !== '80' ? :{d.port} : null} ({d.site_name})
{hasCert(d.name) ? ( Cert ) : ( { setRequestDomain(d) setRequestEmail('') }} > {requesting === d.name ? ( ) : ( 'Request SSL' )} )}
)) )}
Certificates
{certificates.length === 0 ? (
No certificates yet
) : ( certificates.map((c) => (
{c.name}
)) )}
setRequestDomain(null)} centered> Request SSL for {requestDomain?.name} {requestDomain ? (
setRequestEmail(e.target.value)} placeholder="admin@example.com" className="form-control" required />
setRequestDomain(null)}> Cancel {requesting ? 'Requesting…' : 'Request'}
) : null}
) }