Commit Graph

12 Commits

Author SHA1 Message Date
markmorado
09186e23b9 Security audit: tenant isolation, injection fixes, hardening and performance
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
Deploy to Production / backend-tests (push) Has been cancelled
Deploy to Production / frontend-build (push) Has been cancelled
Frontend Checks / Build & typecheck (push) Has been cancelled
SonarCloud / SonarCloud Analysis (push) Has been cancelled
Deploy to Production / Trigger production update (push) Has been cancelled
Security
- Enforce guest ownership and server assignment across Proxmox endpoints
  (VM/LXC actions, firewall, backups, tasks, bulk operations, deploy,
  LXC/ISO creation, golden template) and WebSocket channels
- Keep the panel's PVE root ticket server-side for consoles; single-use
  WebSocket tickets instead of the JWT in URLs; re-check access on open
  WebSocket bridges
- Validate identifiers that reach Proxmox API paths and node shell
  commands; reject backup archives / foreign volumes in create requests
- Close privilege escalation in user management, TOTP replay, reset-link
  poisoning, X-Forwarded-For spoofing, stored XSS (group icons, SVG logos)
- SSH host key pinning (TOFU), encrypted 2FA seeds and notification
  secrets, password changes end other sessions, redact secrets in logs
- Quotas count in-flight creations; 2FA failures count toward lockout

Fixes
- Consoles on non-default API ports, large App Store/script files,
  interrupted tasks after restart, impersonation lost on token refresh,
  HTTPExceptions swallowed into 500s, WebSocket client reconnects

Performance and process
- Fewer DB writes and queries on hot paths, lazy-loaded locales and
  heavy pages, off-loop blocking work, indexes (migrations 44-46)
- Deploy waits for backend tests and frontend build; frontend checks
  workflow; API bound to loopback without the SSL profile
2026-10-23 00:04:16 +05:00
markmorado
25899866bc feat(appstore): глобальный трей свёрнутых операций, переживающий навигацию и перезагрузку
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 9s
Свёрнутые долгие операции (установка приложения, сборка золотого шаблона)
теперь живут в глобальном zustand-сторе (persist в localStorage) и
рендерятся треем MinimizedOpsTray в AppLayout, а не самим диалогом:

- плашка переживает навигацию между страницами и перезагрузку вкладки;
  прогресс опрашивает сам трей (REST, 3с) независимо от диалога
- клик по плашке возвращает на страницу операции и разворачивает диалог:
  установка — resume-режим InstallWizard (resumeInstall в navigation
  state), шаблон — openGolden с предвыбранным сервером
- «Свернуть» добавляет операцию в трей и закрывает диалог; крестик на
  плашке только убирает её (операция продолжается на сервере)
- плашки несуществующих операций (404 после перезагрузки) трей убирает сам

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 14:13:42 +05:00
markmorado
4621ffe88a fix(appstore): data files, надёжность установки/удаления и сворачиваемые диалоги
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 57s
Deploy to Production / Trigger production update (push) Successful in 8s
Доставка файлов приложения из каталога (data_files) до compose up,
APP_PASSWORD/default_credentials для Umbrel, сворачивание диалогов
долгих операций (MinimizableDialog), фильтрация pull-шума в ошибках.

Исправления багов:
- teardown: отсутствующий в Proxmox CT считается удалённым — orphaned-приложение
  теперь можно удалить из БД
- install: сдвиг VMID мимо занятых записей (nextid не резервирует номер,
  retry мог подхватить чужой контейнер)
- retry: параметры установки сохраняются в installed_apps.install_params
  (cores/memory/disk/storage/bridge/ip_config/port_explicit, миграция JSONB)
  вместо жёстких дефолтов
- reconcile: недоступный сервер больше не помечает все приложения orphaned
- update: реально опубликованный порт фиксируется в БД (url/health)
- .env: значения с '#' кавычатся (dotenv-парсер обрезал их как inline-комментарий)
- порт 80, выбранный явно в мастере, публикуется как есть
- useCatalog: available_only включён в queryKey (коллизия кэша)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 12:52:14 +05:00
markmorado
6a79dd2048 fix(appstore): DNS, per-server golden template, bind-mount perms, delete race
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m1s
Deploy to Production / Trigger production update (push) Successful in 8s
App Store install/update pipeline reliability fixes:
- explicit nameserver (APPSTORE_NAMESERVER) on App Store LXCs and the golden
  template build CT, instead of inheriting a node resolver that may be
  unreachable from the container network (e.g. Tailscale-only DNS)
- golden template storage/resolution moved from one global setting to
  per-server_id (migration 37: app_operations.server_id) — building it on one
  Proxmox server no longer overwrites the template configured for another
- golden template automated build fixed: vzdump export step no longer fails
  on "unable to parse directory volume name 'vztmpl/probe'"
- bind-mount host directories are pre-created with permissive ownership
  before `docker compose up`, fixing Permission denied for non-root
  containers (e.g. MariaDB) writing to Docker-auto-created root-owned dirs
- delete/teardown now waits for Proxmox to actually confirm the destroy task
  finished (was silently proceeding after a short timeout, letting a new
  install reuse the VMID while the node was still wiping the old disk)
- pct create retries a few times on transient "got lock" config errors
- failed pipeline steps now report the tail of command output (4000 chars)
  instead of the head, so the real error isn't buried under pull/progress noise
- install error box in the UI wraps long text and scrolls instead of
  stretching the dialog

Also carries forward in-progress script catalog / instances / RBAC changes
that were already uncommitted in the working tree before this session.

Bump to v1.9.1, update WIKI.md/docs/CHANGELOG accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 04:49:40 +05:00
markmorado
b8536ac2e8 feat(instances): command palette, unified nav, расширенное меню инстанса и правки табов
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
- Командная палитра (Ctrl+K) с общим реестром nav-items и его store
- Новые общие UI-примитивы: alert, breadcrumb, checkbox, progress, switch, textarea
- Меню инстанса: добавлены «Параметры», «Мигрировать», «Изменить ресурсы»,
  «Создать резервную копию» (новый BackupDialog) и «Удалить»; исправлено
  закрытие меню при живом обновлении списка (стабильные columns + getRowId)
- Вкладки инстанса: «Вычислительные ресурсы», «Опции CPU», «Управление
  дисками» и «Изменение размера диска» перенесены с «Настройки» на
  «Оборудование» для VM (для LXC, у которых нет вкладки «Оборудование»,
  ресурсы и ресайз диска остаются в «Настройках»); общие карточки вынесены
  в ResourceCards.tsx
- Локализация: новые ключи ru/en для добавленных пунктов меню и бэкапа

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 00:58:45 +05:00
markmorado
633f1a424c feat(appstore): кастомный порт при установке + мгновенная чистка инстанса
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 57s
Deploy to Production / Trigger production update (push) Successful in 7s
App Store:
- поле кастомного порта в мастере установки (переопределяет порт каталога)
- валидация диапазона порта 1..65535 (Pydantic Field + EngineError)
- APP_PORT в окружении синхронизируется с выбранным портом
- при удалении приложения инстанс сразу помечается deleted в кэше
  vm_instances (soft_delete_vm_instance), не дожидаясь фонового воркера

Также включены правки IPAM (привязка сетей к рабочей области, UI
WorkspaceSelect) и синхронизации каталога App Store.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 01:20:28 +05:00
markmorado
a6eeae3dd7 feat(ipam): привязка сетей к серверу/ноде и автовыбор сети в визардах
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
- network-scope: scopedNetworks/autoPickNetworkId — фильтрация IPAM-сетей по
  выбранным серверу/ноде и детерминированный автовыбор сети для выдачи IP
- ServerNodeSelect: пара селектов «Сервер + Нода» для привязки сети
- Мастер установки App Store и CreateInstanceWizard: список сетей ограничен
  релевантными, при смене сервера/ноды сеть подбирается автоматически
- IPAM: страницы сетей учитывают привязку к ноде
- Исправлены типы обработчиков Select (onValueChange отдаёт string|null)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 20:09:17 +05:00
markmorado
23d3f95f54 fix(appstore): выбор хранилища в мастере установки + видимость реальной ошибки
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 57s
Deploy to Production / Trigger production update (push) Successful in 8s
- Установка: поле «Хранилище» стало выпадающим списком доступных rootdir-хранилищ
  ноды (useLXCStorages) с автовыбором валидного вместо ручного ввода
- Диагностика сбоя: увеличен захват вывода упавшей команды (400 → 2000 символов)
  и добавлен 2>&1 к docker compose pull/up — реальная причина (напр. отсутствие
  тега образа) больше не обрезается за строками warning

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 19:28:39 +05:00
markmorado
e497ae541f fix(appstore): резервный REST-опрос прогресса установки (не зависать при потере WS)
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Мастер установки получал прогресс только по WebSocket; при потерянном
событии (или долгом docker compose up с тяжёлыми образами) UI замирал на
последнем шаге. Добавлен поллинг /operations раз в 3с как фолбэк.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:50:31 +05:00
markmorado
9bfb055f69 feat(appstore): показывать операции App Store в «Задачах» + IP из IPAM при установке
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 55s
Deploy to Production / Trigger production update (push) Successful in 8s
- AppOperation.to_task_dict(): операции install/update/delete/… приведены к
  общему формату и включены в /api/all-tasks, active-count и clear-completed
- Установка приложения: опциональный выбор сети/пула IPAM — статический IP
  вместо DHCP (net0 ip=<addr>/<mask>,gw=…), освобождение адреса при удалении
- Мастер установки: селекторы «Сеть IPAM»/«Пул IPAM» (ru/en), по умолчанию DHCP

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:20:33 +05:00
markmorado
635947eb15 fix(appstore): рендер markdown/скриншотов, фильтр категорий, локализация ошибки, ширина карточек
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 57s
Deploy to Production / Trigger production update (push) Successful in 8s
- Описания приложений: безопасный рендер markdown + HTML (react-markdown +
  remark-gfm + rehype-raw + rehype-sanitize), скриншоты отображаются как картинки
- Фильтр по категории: переведён на надёжную фильтрацию в Python (JSONB-оператор
  на generic JSON-колонке отрабатывал ненадёжно)
- Ошибка отсутствия золотого шаблона локализована (i18n appstore.golden_missing)
- Каталог: карточки шире (макс 3 колонки вместо 4), описание в 3 строки

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 23:28:19 +05:00
markmorado
0606e8ac77 feat(appstore): модуль «App Store» — каталог self-hosted приложений (1 app = 1 LXC + Docker Compose)
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m4s
Deploy to Production / Trigger production update (push) Successful in 12s
Полный цикл M0–M5 по ТЗ:
- Catalog Service: импорт runtipi/runtipi-appstore → catalog_apps, идемпотентный
  синк, кэш логотипов, авто раз в 24ч (APScheduler), флаг update_available.
- App Engine: установка (клон золотого шаблона → pct push compose/.env →
  docker compose up → health-check) с журналом шагов, шифрованием env (Fernet),
  генерацией random-секретов и прогрессом по WebSocket.
- Lifecycle: start/stop/restart/logs/delete + реконсиляция состояния (orphaned).
- Update/Rollback через снапшоты Proxmox (pre-update, хранение последнего 1).
- UI: экраны App Store (сетка/поиск/категории), страница приложения, мастер
  установки (динамическая form_fields + advanced + прогресс + креденшелы),
  My Apps; i18n ru/en; атрибуция Runtipi.
- RBAC app:view/install/manage; только unprivileged LXC; pct exec/push без
  shell-инъекций (base64 + экранирование).
- Модели catalog_apps/installed_apps/app_operations (миграции 31–32).
- Docs: golden-template, appstore-poc/catalog/engine.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 23:05:20 +05:00