Улучшен фронт
1. Добавлен функционал в интерфейс по управлению сертификатами и службой редактирования сертификатов. 2. Добавлена кнопка для добавления прокси и экран редактирования прокси.
This commit is contained in:
@@ -11,6 +11,7 @@ import { $ } from '../utils/dom.js';
|
||||
export class ProxyManager {
|
||||
constructor() {
|
||||
this.proxiesData = [];
|
||||
this.certsCache = {};
|
||||
this.mockData = [
|
||||
{
|
||||
enable: true,
|
||||
@@ -19,6 +20,7 @@ export class ProxyManager {
|
||||
local_port: '3333',
|
||||
service_https_use: false,
|
||||
auto_https: true,
|
||||
auto_create_ssl: true,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
@@ -28,6 +30,7 @@ export class ProxyManager {
|
||||
local_port: '8080',
|
||||
service_https_use: true,
|
||||
auto_https: false,
|
||||
auto_create_ssl: false,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
@@ -37,22 +40,89 @@ export class ProxyManager {
|
||||
local_port: '5000',
|
||||
service_https_use: false,
|
||||
auto_https: false,
|
||||
auto_create_ssl: false,
|
||||
status: 'disabled'
|
||||
}
|
||||
];
|
||||
this.mockCerts = {
|
||||
'git.example.ru': { has_cert: true, is_expired: false, days_left: 60 }
|
||||
};
|
||||
}
|
||||
|
||||
// Загрузить список прокси
|
||||
async load() {
|
||||
if (isWailsAvailable()) {
|
||||
this.proxiesData = await api.getProxyList();
|
||||
await this.loadCertsInfo();
|
||||
} else {
|
||||
// Используем тестовые данные если Wails недоступен
|
||||
this.proxiesData = this.mockData;
|
||||
this.certsCache = this.mockCerts;
|
||||
}
|
||||
this.render();
|
||||
}
|
||||
|
||||
// Загрузить информацию о сертификатах
|
||||
async loadCertsInfo() {
|
||||
const allCerts = await api.getAllCertsInfo();
|
||||
this.certsCache = {};
|
||||
for (const cert of allCerts) {
|
||||
this.certsCache[cert.domain] = cert;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверить соответствие домена wildcard паттерну
|
||||
matchesWildcard(domain, pattern) {
|
||||
if (pattern.startsWith('*.')) {
|
||||
const wildcardBase = pattern.slice(2);
|
||||
const domainParts = domain.split('.');
|
||||
if (domainParts.length >= 2) {
|
||||
const domainBase = domainParts.slice(1).join('.');
|
||||
return domainBase === wildcardBase;
|
||||
}
|
||||
}
|
||||
return domain === pattern;
|
||||
}
|
||||
|
||||
// Найти сертификат для домена (включая wildcard)
|
||||
findCertForDomain(domain) {
|
||||
if (this.certsCache[domain]?.has_cert) {
|
||||
return this.certsCache[domain];
|
||||
}
|
||||
|
||||
const domainParts = domain.split('.');
|
||||
if (domainParts.length >= 2) {
|
||||
const wildcardDomain = '*.' + domainParts.slice(1).join('.');
|
||||
if (this.certsCache[wildcardDomain]?.has_cert) {
|
||||
return this.certsCache[wildcardDomain];
|
||||
}
|
||||
}
|
||||
|
||||
for (const [certDomain, cert] of Object.entries(this.certsCache)) {
|
||||
if (cert.has_cert && cert.dns_names) {
|
||||
for (const dnsName of cert.dns_names) {
|
||||
if (this.matchesWildcard(domain, dnsName)) {
|
||||
return cert;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Получить иконку сертификата для домена
|
||||
getCertIcon(domain) {
|
||||
const cert = this.findCertForDomain(domain);
|
||||
if (cert) {
|
||||
if (cert.is_expired) {
|
||||
return `<span class="cert-icon cert-expired" title="SSL сертификат истёк"><i class="fas fa-shield-alt"></i></span>`;
|
||||
} else {
|
||||
return `<span class="cert-icon cert-valid" title="SSL активен (${cert.days_left} дн.)"><i class="fas fa-shield-alt"></i></span>`;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// Отрисовать список прокси
|
||||
render() {
|
||||
const tbody = $('proxyTable')?.querySelector('tbody');
|
||||
@@ -66,15 +136,17 @@ export class ProxyManager {
|
||||
const httpsBadge = proxy.service_https_use ? 'badge-yes">HTTPS' : 'badge-no">HTTP';
|
||||
const autoHttpsBadge = proxy.auto_https ? 'badge-yes">Да' : 'badge-no">Нет';
|
||||
const protocol = proxy.auto_https ? 'https' : 'http';
|
||||
const certIcon = this.getCertIcon(proxy.external_domain);
|
||||
|
||||
row.innerHTML = `
|
||||
<td><code class="clickable-link" data-url="${protocol}://${proxy.external_domain}">${proxy.external_domain} <i class="fas fa-external-link-alt"></i></code></td>
|
||||
<td>${certIcon}<code class="clickable-link" data-url="${protocol}://${proxy.external_domain}">${proxy.external_domain} <i class="fas fa-external-link-alt"></i></code></td>
|
||||
<td><code>${proxy.local_address}:${proxy.local_port}</code></td>
|
||||
<td><span class="badge ${httpsBadge}</span></td>
|
||||
<td><span class="badge ${autoHttpsBadge}</span></td>
|
||||
<td><span class="badge ${statusBadge}">${proxy.status}</span></td>
|
||||
<td>
|
||||
<button class="icon-btn" data-action="edit-vaccess" data-host="${proxy.external_domain}" data-is-proxy="true" title="vAccess"><i class="fas fa-shield-alt"></i></button>
|
||||
<button class="icon-btn" data-action="edit-vaccess" data-host="${proxy.external_domain}" data-is-proxy="true" title="vAccess"><i class="fas fa-user-lock"></i></button>
|
||||
<button class="icon-btn" data-action="open-certs" data-host="${proxy.external_domain}" data-is-proxy="true" title="SSL сертификаты"><i class="fas fa-shield-alt"></i></button>
|
||||
<button class="icon-btn" data-action="edit-proxy" data-index="${index}" title="Редактировать"><i class="fas fa-edit"></i></button>
|
||||
</td>
|
||||
`;
|
||||
@@ -119,6 +191,11 @@ export class ProxyManager {
|
||||
window.editVAccess(host, isProxy);
|
||||
}
|
||||
break;
|
||||
case 'open-certs':
|
||||
if (window.openCertManager) {
|
||||
window.openCertManager(host, isProxy, []);
|
||||
}
|
||||
break;
|
||||
case 'edit-proxy':
|
||||
if (window.editProxy) {
|
||||
window.editProxy(index);
|
||||
|
||||
Reference in New Issue
Block a user