914 lines
24 KiB
Markdown
914 lines
24 KiB
Markdown
# Руководство по использованию Desktop приложения
|
||
|
||
## Обзор
|
||
|
||
Desktop версия knocker-приложения предоставляет полный функционал порт-простукивания (port knocking) в виде автономного Electron приложения. Поддерживает как работу через внешний API сервер, так и локальное простукивание через Node.js.
|
||
|
||
## Содержание
|
||
|
||
1. [Установка и запуск](#установка-и-запуск)
|
||
2. [Режимы работы](#режимы-работы)
|
||
3. [Конфигурация](#конфигурация)
|
||
4. [API контракты](#api-контракты)
|
||
5. [Локальное простукивание](#локальное-простукивание)
|
||
6. [Интерфейс пользователя](#интерфейс-пользователя)
|
||
7. [Примеры использования](#примеры-использования)
|
||
8. [Устранение неполадок](#устранение-неполадок)
|
||
9. [Разработка](#разработка)
|
||
|
||
---
|
||
|
||
## Установка и запуск
|
||
|
||
### Предварительные требования
|
||
|
||
- **Node.js** v18+
|
||
- **npm** v8+
|
||
- **Операционная система**: Windows, macOS, Linux
|
||
|
||
### Установка зависимостей
|
||
|
||
```bash
|
||
cd desktop
|
||
npm install
|
||
```
|
||
|
||
### Режимы запуска
|
||
|
||
#### Разработка
|
||
|
||
```bash
|
||
npm run dev
|
||
```
|
||
|
||
#### Сборка для продакшена
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
#### Создание исполняемых файлов
|
||
|
||
```bash
|
||
npm run dist
|
||
```
|
||
|
||
#### Упаковка для конкретной платформы
|
||
|
||
```bash
|
||
# Windows
|
||
npm run dist:win
|
||
|
||
# macOS
|
||
npm run dist:mac
|
||
|
||
# Linux
|
||
npm run dist:linux
|
||
```
|
||
|
||
### Переменные окружения
|
||
|
||
```bash
|
||
# Базовый URL API (опционально)
|
||
export KNOCKER_DESKTOP_API_BASE="http://localhost:8080/api/v1"
|
||
|
||
# Запуск в режиме разработки
|
||
npm run dev
|
||
```
|
||
|
||
---
|
||
|
||
## Режимы работы
|
||
|
||
### 1. API режим (по умолчанию)
|
||
|
||
Приложение подключается к внешнему HTTP API серверу для выполнения операций простукивания.
|
||
|
||
**Активация:**
|
||
|
||
- Установить корректный `apiBase` URL в настройках
|
||
- Например: `http://localhost:8080/api/v1`
|
||
|
||
**Возможности:**
|
||
|
||
- ✅ HTTP API простукивание
|
||
- ✅ Шифрование/расшифровка YAML
|
||
- ✅ Полная функциональность backend сервера
|
||
|
||
### 2. Локальный режим
|
||
|
||
Приложение выполняет простукивание напрямую через Node.js сокеты без внешнего API.
|
||
|
||
**Активация:**
|
||
|
||
- Установить `apiBase` в `""` (пустая строка)
|
||
- Или установить `apiBase` в `"internal"`
|
||
|
||
**Возможности:**
|
||
|
||
- ✅ TCP простукивание
|
||
- ✅ UDP простукивание
|
||
- ❌ Шифрование/расшифровка (недоступно)
|
||
- ✅ Автономная работа
|
||
|
||
#### Локальное простукивание с gateway (Rust/Go helper)
|
||
- Если указано `gateway` (IP или имя интерфейса), Electron автоматически запускает встроенный helper из папки `bin/`:
|
||
- `knock-local-rust` (Rust) — используется приоритетно, если присутствует
|
||
- `knock-local` (Go) — используется как fallback, если Rust-бинарь отсутствует
|
||
- Оба helper-а на Linux используют `SO_BINDTODEVICE` для надежной привязки к интерфейсу и обхода VPN/WireGuard.
|
||
- Если `gateway` не указан — используется встроенная Node-реализация без привязки к интерфейсу.
|
||
|
||
Требования при разработке:
|
||
- Для Rust-хелпера ничего дополнительно не требуется (собирается скриптом `npm run rust:build`).
|
||
- Для Go-хелпера должен быть установлен Go toolchain (скрипт `npm run go:build`).
|
||
В релизных сборках оба бинаря включаются автоматически.
|
||
|
||
Важно (TCP): привязка интерфейса (`SO_BINDTODEVICE`) устанавливается до `connect()`. Это гарантирует, что исходящее TCP-соединение пойдёт через указанный интерфейс, а не в туннель.
|
||
|
||
### 3. Переключение между режимами
|
||
|
||
**API → Локальный:**
|
||
|
||
1. Открыть настройки (Ctrl/Cmd + ,)
|
||
2. Установить `apiBase: ""` или `apiBase: "internal"`
|
||
3. Сохранить настройки
|
||
4. Перезапустить приложение
|
||
|
||
**Локальный → API:**
|
||
|
||
1. Открыть настройки
|
||
2. Установить корректный `apiBase` URL
|
||
3. Сохранить настройки
|
||
4. Перезапустить приложение
|
||
|
||
---
|
||
|
||
## Конфигурация
|
||
|
||
### Файл конфигурации
|
||
|
||
Конфигурация сохраняется в: `~/.config/[app-name]/config.json`
|
||
|
||
**Структура конфигурации:**
|
||
|
||
```json
|
||
{
|
||
"apiBase": "http://localhost:8080/api/v1",
|
||
"gateway": "default-gateway",
|
||
"inlineTargets": "tcp:127.0.0.1:22;tcp:192.168.1.1:80",
|
||
"delay": "1s"
|
||
}
|
||
```
|
||
|
||
### Поля конфигурации
|
||
|
||
| Поле | Тип | Описание | По умолчанию |
|
||
|------|-----|----------|--------------|
|
||
| `apiBase` | string | URL API сервера или "internal" | `http://localhost:8080/api/v1` |
|
||
| `gateway` | string | Шлюз по умолчанию | `""` |
|
||
| `inlineTargets` | string | Цели в inline формате | `""` |
|
||
| `delay` | string | Задержка между целями | `"1s"` |
|
||
|
||
### Редактирование конфигурации
|
||
|
||
**Через интерфейс:**
|
||
|
||
1. Меню → Настройки
|
||
2. Редактирование JSON в текстовом поле
|
||
3. Кнопка "Сохранить"
|
||
|
||
**Программно:**
|
||
|
||
```javascript
|
||
// Получить значение
|
||
const apiBase = await window.api.getConfig('apiBase');
|
||
|
||
// Установить значение
|
||
await window.api.setConfig('apiBase', 'http://new-api.com');
|
||
|
||
// Получить всю конфигурацию
|
||
const config = await window.api.getAllConfig();
|
||
|
||
// Установить всю конфигурацию
|
||
await window.api.setAllConfig(newConfig);
|
||
```
|
||
|
||
---
|
||
|
||
## API контракты
|
||
|
||
### HTTP API Endpoints (для API режима)
|
||
|
||
#### 1. Выполнение простукивания
|
||
|
||
**POST** `/api/v1/knock-actions/execute`
|
||
|
||
**Headers:**
|
||
|
||
``` text
|
||
Content-Type: application/json
|
||
Authorization: Basic <base64(username:password)>
|
||
```
|
||
|
||
**Body (YAML режим):**
|
||
|
||
```json
|
||
{
|
||
"config_yaml": "targets:\n - protocol: tcp\n host: 127.0.0.1\n ports: [22, 80]\ndelay: 1s"
|
||
}
|
||
```
|
||
|
||
**Body (Inline режим):**
|
||
|
||
```json
|
||
{
|
||
"targets": "tcp:127.0.0.1:22;tcp:192.168.1.1:80",
|
||
"delay": "1s",
|
||
"verbose": true,
|
||
"waitConnection": false,
|
||
"gateway": "gateway.com"
|
||
}
|
||
```
|
||
|
||
**Body (Form режим):**
|
||
|
||
```json
|
||
{
|
||
"targets": "tcp:127.0.0.1:22;tcp:192.168.1.1:80",
|
||
"delay": "2s",
|
||
"verbose": true,
|
||
"waitConnection": true
|
||
}
|
||
```
|
||
|
||
**Response:**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Knocking completed successfully"
|
||
}
|
||
```
|
||
|
||
#### 2. Шифрование YAML
|
||
|
||
**POST** `/api/v1/knock-actions/encrypt`
|
||
|
||
**Headers:**
|
||
|
||
``` text
|
||
Content-Type: application/json
|
||
Authorization: Basic <base64(username:password)>
|
||
```
|
||
|
||
**Body:**
|
||
|
||
```json
|
||
{
|
||
"yaml": "targets:\n - protocol: tcp\n host: 127.0.0.1\n ports: [22]"
|
||
}
|
||
```
|
||
|
||
**Response:**
|
||
|
||
```json
|
||
{
|
||
"encrypted": "ENCRYPTED:base64-encoded-data"
|
||
}
|
||
```
|
||
|
||
#### 3. Расшифровка YAML
|
||
|
||
**POST** `/api/v1/knock-actions/decrypt`
|
||
|
||
**Headers:**
|
||
|
||
``` text
|
||
Content-Type: application/json
|
||
Authorization: Basic <base64(username:password)>
|
||
```
|
||
|
||
**Body:**
|
||
|
||
```json
|
||
{
|
||
"encrypted": "ENCRYPTED:base64-encoded-data"
|
||
}
|
||
```
|
||
|
||
**Response:**
|
||
|
||
```json
|
||
{
|
||
"yaml": "targets:\n - protocol: tcp\n host: 127.0.0.1\n ports: [22]"
|
||
}
|
||
```
|
||
|
||
### IPC API (для локального режима)
|
||
|
||
#### Локальное простукивание
|
||
|
||
**Channel:** `knock:local`
|
||
|
||
**Request:**
|
||
|
||
```javascript
|
||
{
|
||
targets: string[], // ["tcp:127.0.0.1:22", "udp:192.168.1.1:53"]
|
||
delay: string, // "1s", "2m", "500ms"
|
||
verbose: boolean, // true/false
|
||
gateway: string // "192.168.1.1" (опционально)
|
||
}
|
||
```
|
||
|
||
**Response:**
|
||
|
||
```javascript
|
||
{
|
||
success: boolean,
|
||
results: [
|
||
{
|
||
target: string,
|
||
success: boolean,
|
||
message: string
|
||
}
|
||
],
|
||
summary: {
|
||
total: number,
|
||
successful: number,
|
||
failed: number
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Локальное простукивание _
|
||
|
||
### Поддерживаемые протоколы
|
||
|
||
- **TCP** - создание соединения и немедленное закрытие
|
||
- **UDP** - отправка пакета данных (fire-and-forget)
|
||
|
||
### Формат целей
|
||
|
||
``` text
|
||
protocol:host:port[:gateway]
|
||
```
|
||
|
||
**Примеры:**
|
||
|
||
- `tcp:127.0.0.1:22`
|
||
- `udp:192.168.1.1:53`
|
||
- `tcp:example.com:80:gateway.com`
|
||
|
||
### Поддержка Gateway
|
||
|
||
Gateway можно указать двумя способами:
|
||
|
||
1. **В строке цели**: `tcp:host:port:gateway_ip`
|
||
2. **Глобально через поле Gateway**: используется для всех целей, если не указан в самой цели
|
||
|
||
**Приоритет gateway:**
|
||
|
||
- Gateway из строки цели имеет приоритет над глобальным
|
||
- Если gateway не указан, используется системный маршрут по умолчанию
|
||
|
||
**Примеры использования gateway:**
|
||
|
||
``` text
|
||
tcp:192.168.1.100:22:192.168.1.1 # Через конкретный gateway
|
||
tcp:127.0.0.1:22 # Системный маршрут
|
||
udp:example.com:53 # Системный маршрут
|
||
```
|
||
|
||
### Формат задержек
|
||
|
||
- `1s` - 1 секунда
|
||
- `500ms` - 500 миллисекунд (не поддерживается, используйте `0.5s`)
|
||
- `2m` - 2 минуты
|
||
- `1h` - 1 час
|
||
|
||
### Таймауты
|
||
|
||
- **TCP**: 5 секунд по умолчанию
|
||
- **UDP**: 5 секунд по умолчанию
|
||
|
||
### Примеры локального простукивания
|
||
|
||
```javascript
|
||
// Простое TCP простукивание
|
||
const result = await window.api.localKnock({
|
||
targets: ["tcp:127.0.0.1:22"],
|
||
delay: "1s",
|
||
verbose: true
|
||
});
|
||
|
||
// Множественные цели
|
||
const result = await window.api.localKnock({
|
||
targets: [
|
||
"tcp:127.0.0.1:22",
|
||
"udp:192.168.1.1:53",
|
||
"tcp:example.com:80"
|
||
],
|
||
delay: "2s",
|
||
verbose: false
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## Интерфейс пользователя
|
||
|
||
### Главное окно
|
||
|
||
#### Поля конфигурации _
|
||
|
||
- **API URL** - адрес API сервера или "internal" для локального режима
|
||
- **Gateway** - шлюз по умолчанию
|
||
- **Password** - пароль для аутентификации
|
||
|
||
#### Режимы работы _
|
||
|
||
1. **Inline** - простой текстовый формат целей
|
||
2. **YAML** - структурированная YAML конфигурация
|
||
3. **Form** - графический редактор целей
|
||
|
||
#### Inline режим
|
||
|
||
- **Targets** - цели в формате `protocol:host:port;protocol:host:port`
|
||
- **Delay** - задержка между целями
|
||
- **Verbose** - подробный вывод
|
||
- **Wait Connection** - ожидание соединения
|
||
- **Gateway** - шлюз
|
||
|
||
#### YAML режим
|
||
|
||
- **Config YAML** - YAML конфигурация
|
||
- **Server File Path** - путь к файлу на сервере
|
||
- **Encrypt/Decrypt** - шифрование/расшифровка
|
||
|
||
#### Form режим
|
||
|
||
- **Targets List** - список целей с возможностью редактирования
|
||
- **Add Target** - добавление новой цели
|
||
- **Remove** - удаление цели
|
||
|
||
### Меню приложения
|
||
|
||
#### Файл
|
||
|
||
- **Открыть файл** - загрузка YAML конфигурации
|
||
- **Сохранить как** - сохранение текущей конфигурации
|
||
- **Выход** - закрытие приложения
|
||
|
||
#### Настройки
|
||
|
||
- **Настройки** - открытие окна конфигурации
|
||
|
||
#### Справка
|
||
|
||
- **О программе** - информация о версии
|
||
- **Документация** - ссылки на документацию
|
||
|
||
### Окно настроек
|
||
|
||
#### Редактирование конфигурации _
|
||
|
||
- **JSON Editor** - многострочное поле для редактирования
|
||
- **Save** - сохранение изменений
|
||
- **Return** - возврат к главному окну
|
||
|
||
#### Валидация
|
||
|
||
- Автоматическая проверка JSON синтаксиса
|
||
- Отображение ошибок валидации
|
||
- Предотвращение сохранения некорректных данных
|
||
|
||
---
|
||
|
||
## Примеры использования
|
||
|
||
### Пример 1: Базовое простукивание SSH
|
||
|
||
**Цель:** Открыть SSH доступ к серверу
|
||
|
||
**Конфигурация:**
|
||
|
||
```json
|
||
{
|
||
"apiBase": "internal",
|
||
"gateway": "",
|
||
"inlineTargets": "tcp:192.168.1.100:22",
|
||
"delay": "1s"
|
||
}
|
||
```
|
||
|
||
**Шаги:**
|
||
|
||
1. Установить режим "Inline"
|
||
2. Ввести цель: `tcp:192.168.1.100:22`
|
||
3. Установить задержку: `1s`
|
||
4. Нажать "Выполнить"
|
||
|
||
### Пример 2: Множественные цели
|
||
|
||
**Цель:** Простучать несколько сервисов
|
||
|
||
**Конфигурация:**
|
||
|
||
``` text
|
||
tcp:server1.com:22;tcp:server1.com:80;udp:server2.com:53
|
||
```
|
||
|
||
**Задержка:** `2s`
|
||
|
||
### Пример 3: YAML конфигурация
|
||
|
||
**Файл конфигурации:**
|
||
|
||
```yaml
|
||
targets:
|
||
- protocol: tcp
|
||
host: 127.0.0.1
|
||
ports: [22, 80, 443]
|
||
wait_connection: true
|
||
- protocol: udp
|
||
host: 192.168.1.1
|
||
ports: [53, 123]
|
||
delay: 1s
|
||
path: /etc/knocker/config.yaml
|
||
```
|
||
|
||
### Пример 4: Шифрование конфигурации
|
||
|
||
**Шаги:**
|
||
|
||
1. Создать YAML конфигурацию
|
||
2. Установить пароль
|
||
3. Нажать "Зашифровать"
|
||
4. Сохранить зашифрованный файл
|
||
|
||
### Пример 5: Локальный режим с множественными целями
|
||
|
||
**Конфигурация для локального режима:**
|
||
|
||
```json
|
||
{
|
||
"apiBase": "internal",
|
||
"inlineTargets": "tcp:127.0.0.1:22;tcp:127.0.0.1:80;udp:127.0.0.1:53",
|
||
"delay": "1s"
|
||
}
|
||
```
|
||
|
||
### Пример 6: Использование Gateway
|
||
|
||
**Простукивание через определенный интерфейс:**
|
||
|
||
```json
|
||
{
|
||
"apiBase": "internal",
|
||
"gateway": "192.168.1.1",
|
||
"inlineTargets": "tcp:192.168.1.100:22",
|
||
"delay": "1s"
|
||
}
|
||
```
|
||
|
||
**Смешанное использование gateway:**
|
||
|
||
``` text
|
||
tcp:127.0.0.1:22;tcp:192.168.1.100:22:192.168.1.1;udp:example.com:53
|
||
```
|
||
|
||
- Первая цель: без gateway (системный маршрут)
|
||
- Вторая цель: через gateway 192.168.1.1
|
||
- Третья цель: без gateway
|
||
|
||
Замечания по ошибкам:
|
||
- Если указан несуществующий интерфейс в `gateway`, helper вернёт критическую ошибку и код выхода 1.
|
||
- При `waitConnection: false` сетевые отказы соединения трактуются как предупреждения, но ошибки привязки к интерфейсу — всегда ошибки.
|
||
|
||
---
|
||
|
||
## Устранение неполадок
|
||
|
||
### Общие проблемы
|
||
|
||
#### Проблема: "API URL не доступен"
|
||
|
||
**Симптомы:**
|
||
|
||
- Ошибки подключения к API
|
||
- Таймауты при выполнении операций
|
||
|
||
**Решения:**
|
||
|
||
1. Проверить доступность API сервера
|
||
2. Проверить правильность URL
|
||
3. Проверить настройки файрвола
|
||
4. Переключиться в локальный режим
|
||
|
||
#### Проблема: "Неправильный пароль"
|
||
|
||
**Симптомы:**
|
||
|
||
- HTTP 401 ошибки
|
||
- Отказ в доступе при шифровании
|
||
|
||
**Решения:**
|
||
|
||
1. Проверить правильность пароля
|
||
2. Убедиться в корректности base64 кодирования
|
||
3. Проверить настройки аутентификации на сервере
|
||
|
||
#### Проблема: "Файл не найден"
|
||
|
||
**Симптомы:**
|
||
|
||
- Ошибки при открытии файлов
|
||
- "File not found" при сохранении
|
||
|
||
**Решения:**
|
||
|
||
1. Проверить права доступа к файлам
|
||
2. Убедиться в существовании директорий
|
||
3. Проверить путь к файлу
|
||
|
||
### Проблемы локального режима
|
||
|
||
#### Проблема: "No targets provided"
|
||
|
||
**Причина:** Не удалось извлечь цели из конфигурации
|
||
|
||
**Решение:**
|
||
|
||
1. Проверить заполнение поля targets
|
||
2. Убедиться в корректности формата
|
||
3. Проверить режим работы (inline/yaml/form)
|
||
|
||
#### Проблема: "Unsupported protocol"
|
||
|
||
**Причина:** Использован неподдерживаемый протокол
|
||
|
||
**Решение:**
|
||
|
||
- Использовать только `tcp` или `udp`
|
||
- Проверить синтаксис: `protocol:host:port`
|
||
|
||
#### Проблема: "Connection timeout"
|
||
|
||
**Причина:** Цель недоступна или заблокирована
|
||
|
||
**Решение:**
|
||
|
||
1. Проверить доступность цели
|
||
2. Проверить настройки файрвола
|
||
3. Убедиться в правильности IP/порта
|
||
|
||
### Проблемы конфигурации
|
||
|
||
#### Проблема: "Invalid JSON"
|
||
|
||
**Симптомы:**
|
||
|
||
- Ошибки при сохранении настроек
|
||
- Невозможность загрузить конфигурацию
|
||
|
||
**Решения:**
|
||
|
||
1. Проверить синтаксис JSON
|
||
2. Использовать валидатор JSON
|
||
3. Проверить экранирование специальных символов
|
||
|
||
#### Проблема: "Настройки не сохраняются"
|
||
|
||
**Причина:** Проблемы с правами доступа
|
||
|
||
**Решение:**
|
||
|
||
1. Проверить права записи в директорию конфигурации
|
||
2. Запустить от имени администратора (если необходимо)
|
||
3. Проверить свободное место на диске
|
||
|
||
### Диагностика
|
||
|
||
#### Логи приложения
|
||
|
||
```bash
|
||
# Windows
|
||
%APPDATA%/[app-name]/logs/
|
||
|
||
# macOS
|
||
~/Library/Logs/[app-name]/
|
||
|
||
# Linux
|
||
~/.config/[app-name]/logs/
|
||
```
|
||
|
||
#### DevTools
|
||
|
||
1. Открыть DevTools (F12)
|
||
2. Проверить Console на ошибки
|
||
3. Проверить Network для API запросов
|
||
4. Проверить Application → Local Storage
|
||
|
||
#### Командная строка
|
||
|
||
```bash
|
||
# Запуск с отладкой
|
||
npm run dev -- --enable-logging
|
||
|
||
# Проверка переменных окружения
|
||
echo $KNOCKER_DESKTOP_API_BASE
|
||
```
|
||
|
||
---
|
||
|
||
## Разработка _
|
||
|
||
### Структура проекта
|
||
|
||
``` text
|
||
desktop/
|
||
├── src/
|
||
│ ├── main/ # Main процесс
|
||
│ │ └── main.js # Основная логика
|
||
│ ├── preload/ # Preload скрипты
|
||
│ │ └── preload.js # IPC мост
|
||
│ └── renderer/ # Renderer процесс
|
||
│ ├── index.html # Главная страница
|
||
│ ├── renderer.js # UI логика
|
||
│ ├── settings.html # Страница настроек
|
||
│ └── settings.js # Логика настроек
|
||
├── package.json # Зависимости и скрипты
|
||
├── electron-builder.yml # Конфигурация сборки
|
||
└── README.md # Документация
|
||
```
|
||
|
||
### Ключевые файлы
|
||
|
||
#### `src/main/main.js`
|
||
|
||
- Создание и управление окнами
|
||
- IPC обработчики
|
||
- Локальное простукивание
|
||
- Файловые операции
|
||
|
||
#### `src/preload/preload.js`
|
||
|
||
- Безопасный мост между процессами
|
||
- Экспорт API в renderer
|
||
|
||
#### `src/renderer/renderer.js`
|
||
|
||
- UI логика
|
||
- Обработка пользовательского ввода
|
||
- HTTP запросы к API
|
||
|
||
### Добавление новых функций
|
||
|
||
#### 1. Новый IPC метод
|
||
|
||
**В main.js:**
|
||
|
||
```javascript
|
||
ipcMain.handle('new:method', async (_e, payload) => {
|
||
// Логика метода
|
||
return { success: true, data: result };
|
||
});
|
||
```
|
||
|
||
**В preload.js:**
|
||
|
||
```javascript
|
||
contextBridge.exposeInMainWorld('api', {
|
||
// ... существующие методы
|
||
newMethod: async (payload) => ipcRenderer.invoke('new:method', payload)
|
||
});
|
||
```
|
||
|
||
**В renderer.js:**
|
||
|
||
```javascript
|
||
const result = await window.api.newMethod(data);
|
||
```
|
||
|
||
#### 2. Новый UI элемент
|
||
|
||
**В index.html:**
|
||
|
||
```html
|
||
<button id="newButton">Новая функция</button>
|
||
```
|
||
|
||
**В renderer.js:**
|
||
|
||
```javascript
|
||
qsi('#newButton')?.addEventListener('click', async () => {
|
||
// Логика обработки
|
||
});
|
||
```
|
||
|
||
### Тестирование
|
||
|
||
#### Unit тесты
|
||
|
||
```bash
|
||
npm test
|
||
```
|
||
|
||
#### Интеграционные тесты
|
||
|
||
```bash
|
||
npm run test:integration
|
||
```
|
||
|
||
#### E2E тесты
|
||
|
||
```bash
|
||
npm run test:e2e
|
||
```
|
||
|
||
### Сборка и деплой
|
||
|
||
#### Локальная сборка
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
#### Создание дистрибутивов
|
||
|
||
```bash
|
||
npm run dist
|
||
```
|
||
|
||
#### Автоматические релизы
|
||
|
||
```bash
|
||
npm run release
|
||
```
|
||
|
||
### Отладка
|
||
|
||
#### DevTools _
|
||
|
||
- **Main процесс**: `--inspect` флаг
|
||
- **Renderer процесс**: F12 в приложении
|
||
|
||
#### Логирование
|
||
|
||
```javascript
|
||
console.log('Debug info:', data);
|
||
console.error('Error:', error);
|
||
```
|
||
|
||
#### Профилирование
|
||
|
||
```bash
|
||
npm run dev -- --enable-profiling
|
||
```
|
||
|
||
---
|
||
|
||
## Безопасность
|
||
|
||
### Рекомендации
|
||
|
||
1. **Пароли**: Используйте сильные пароли для аутентификации
|
||
2. **Сеть**: Ограничьте доступ к API серверу
|
||
3. **Файлы**: Не храните пароли в открытом виде
|
||
4. **Обновления**: Регулярно обновляйте приложение
|
||
|
||
### Ограничения
|
||
|
||
- Локальное простукивание выполняется с правами пользователя
|
||
- Не требует root/administrator прав
|
||
- Подчиняется системным ограничениям сетевого доступа
|
||
|
||
---
|
||
|
||
## Поддержка
|
||
|
||
### Контакты
|
||
|
||
- **Документация**: [LOCAL_KNOCKING.md](./LOCAL_KNOCKING.md)
|
||
- **Исходный код**: [GitHub Repository]
|
||
- **Issues**: [GitHub Issues]
|
||
|
||
### Версии
|
||
|
||
- **Текущая версия**: 1.0
|
||
- **Electron**: v28+
|
||
- **Node.js**: v18+
|
||
|
||
### Лицензия
|
||
|
||
[Указать лицензию]
|
||
|
||
---
|
||
|
||
**Версия документации**: 1.0
|
||
**Дата создания**: 2024
|
||
**Совместимость**: Electron Desktop App v1.0+
|