Files
2026-08-20 04:18:32 +09:00

9.1 KiB

reg — панель регистрации DMR ID

Небольшой PHP-скрипт для радиолюбительского DMR-сервера (XLX/HBLink, узел DMRYKT). Решает одну задачу: выдача и учёт локальных DMR ID. Радиолюбитель заполняет заявку с позывным и контактом в Telegram, скрипт присваивает свободный ID из диапазона 1410000–1419999 и кладёт заявку в очередь. Администратор через веб-админку подтверждает, редактирует, блокирует или удаляет записи, после чего подтверждённые записи выгружаются в файл dmrid.dat формата ID;CALLSIGN;, который читают XLX и Pi-Star.

Базы данных нет: всё хранится в JSON-файле и в текстовом .dat.

Стек

  • PHP (процедурный, без фреймворка и без Composer). Версия не определена из кода, но используются стрелочные функции — требуется PHP 7.4+.
  • Хранилище: db.json (структура {"count": N, "results": [...]}) и dmrid.dat (ID;CALLSIGN; построчно).
  • Frontend: HTML, CSS, ванильный JavaScript (клиентская валидация и AJAX-проверка уникальности).
  • Веб-сервер с PHP — по README ожидается размещение в /var/www/xlxd/reg рядом с XLX-сервером.
  • Внешних API нет.

Структура

Путь Назначение
index.php Стартовая страница со ссылками на админку, XLX-сервер и файлы баз
register.php Публичная форма заявки на DMR ID: валидация позывного и Telegram, генерация свободного ID, запись в db.json с confirmed: false
admin.php Админка: HTML, таблица подтверждённых записей, поиск, сортировка, пагинация, форма добавления вручную
adminLogic.php Вся логика админки, подключается первой строкой admin.php. Обрабатывает sync, confirm, block, delete, edit, ajax_check, добавление через POST, а также поиск, сортировку и пагинацию
check_unique.php Отдельный JSON-эндпоинт проверки уникальности ID и позывного по db.json и dmrid.dat
db.json Основная база заявок и записей
dmrid.dat Выгрузка подтверждённых записей для XLX/Pi-Star
assets/css/style.css Стили админки
assets/js/main.js Клиентская валидация формы добавления и AJAX-проверка уникальности
savedata/ Резервная копия предыдущей версии: admin.php, logic.php, db.json (232 записи), dmrid.dat
README Исходное описание структуры проекта от автора
README.upstream.md Исходная инструкция по установке от автора

Как запустить

Отдельного запуска нет — это набор PHP-файлов, который кладётся в корень веб-сервера. По инструкции автора (README.upstream.md):

git clone <репозиторий> /var/www/xlxd/reg
chmod 666 /var/www/xlxd/reg/db.json
chmod 666 /var/www/xlxd/reg/dmrid.dat
ln -s /var/www/xlxd/reg/dmrid.dat /xlxd/dmrid.dat

Адреса после установки:

  • админка — https://ваш-сайт/reg/
  • форма регистрации — https://ваш-сайт/reg/register.php

Права 666 на файлы данных обязательны: процесс PHP пишет в них напрямую через file_put_contents.

Конфигурация

Файлов конфигурации и переменных окружения нет. Всё, что можно поменять, захардкожено в исходниках:

Что Где Значение
Пути к файлам данных adminLogic.php, register.php, check_unique.php __DIR__ . '/db.json', __DIR__ . '/dmrid.dat'
Диапазон выдаваемых ID register.php rand(1410000, 1419999)
Формат позывного register.php, adminLogic.php /^[A-Z0-9]{4,7}$/
Формат Telegram register.php /^[a-zA-Z0-9_]{5,32}$/
Допустимый ID при ручном добавлении adminLogic.php 6–7 цифр, от 100000 до 9999999
Записей на страницу adminLogic.php $perPage = 15
Ссылки на внешние ресурсы index.php, admin.php https://xlx.dmrykt.ru/, https://dmrykt.ru/
Путь к стилям admin.php /reg/assets/css/style.css — приложение обязано лежать в подкаталоге /reg

Состояние

Рабочий, но простой скрипт; развитие остановлено. 8 коммитов, последний — 12.07.2025, из них четыре последних правили только README. Реального кода — один заход «Add files via upload» 11.07.2025.

Функциональность закрыта: заявка, подтверждение, редактирование, блокировка, удаление, синхронизация в .dat, поиск, сортировка, пагинация. db.json и dmrid.dat в репозитории пустые — боевые данные вычищены, но в savedata/ лежит старый снимок на 232 записи.

Что не доделано

  • Админка полностью открыта. В admin.php и adminLogic.php нет ни аутентификации, ни проверки сессии, ни CSRF-токенов. Любой, кто знает адрес, может добавлять, редактировать, блокировать и удалять записи обычными GET-запросами вида admin.php?delete=1410001. Прикрывать доступ нужно на уровне веб-сервера (basic auth или ограничение по IP).
  • Нет блокировок при записи. file_get_contents + file_put_contents без flock: две одновременные заявки могут затереть друг друга.
  • Обработчик edit в adminLogic.php дублирует работу: сначала точечно правит строку в dmrid.dat, а следом полностью перезаписывает файл из всех записей db.json — включая неподтверждённые. Это расходится с логикой sync, которая пишет только подтверждённые.
  • В check_unique.php разбор db.json идёт по верхнему уровню (foreach ($json as $entry)), а не по $json['results'] — проверка по JSON-базе фактически не работает. Этот файл к тому же дублирует ajax_check из adminLogic.php и, судя по коду фронтенда, не вызывается.
  • Сравнение $item['id'] === $confirmId строгое, а ID в db.json может оказаться строкой — тогда подтверждение и блокировка молча ничего не сделают.
  • В admin.php в шапке таблицы (<thead>) используется $row['id'] вне цикла — обращение к неопределённой переменной.
  • Сообщения об ошибках выводятся без htmlspecialchars в register.php, хотя тексты и константные.
  • Заявки принимаются без капчи и без ограничения частоты — форма открыта для спама.
  • В README.upstream.md указан адрес кошелька USDT (TRC20) для донатов — при публикации репозитория стоит решить, нужен ли он там.
  • В savedata/db.json лежат персональные данные пользователей: позывные, имена, фамилии, города и Telegram-контакты 232 человек. Перед тем как делать репозиторий публичным, этот файл лучше убрать.
  • Тестов нет, CI нет, логирования действий администратора нет.