# Sign3x — Простая электронная подпись для MODX 3

Sign3x — компонент для MODX 3, реализующий хранение, управление и подписание PDF-документов **простой электронной подписью (ПЭП)** в соответствии с Федеральным законом № 63-ФЗ «Об электронной подписи». Подпись фиксирует ФИО подписанта, должность, дату/время и уникальный SHA-256 хэш-ключ.  
https://extras.modx.com/package/sign3x

# Документация

Sign3x — компонент для MODX 3, реализующий хранение, управление и подписание PDF-документов **простой электронной подписью (ПЭП)** в соответствии с Федеральным законом № 63-ФЗ «Об электронной подписи». Подпись фиксирует ФИО подписанта, должность, дату/время и уникальный SHA-256 хэш-ключ.

## 1. Требования

<table id="bkmrk-%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82-%D0%92%D0%B5%D1%80%D1%81%D0%B8%D1%8F-%D0%9F%D1%80%D0%B8"><thead><tr><th>Компонент</th><th>Версия</th><th>Примечание</th></tr></thead><tbody><tr><td>MODX Revolution</td><td>3.x</td><td>Обязательно</td></tr><tr><td>PHP</td><td>8.1 или выше</td><td>Обязательно</td></tr><tr><td>MySQL / MariaDB</td><td>любая актуальная</td><td>Обязательно</td></tr><tr><td>pdoTools</td><td>любая актуальная</td><td>Необязательно — нужно только при использовании Fenom-шаблонов (`&fenom=`1``)</td></tr><tr><td>FPDI + TCPDF</td><td>—</td><td>Входят в пакет — нужны только для визуального штампа в PDF</td></tr></tbody></table>

## 2. Установка

1. Установите пакет через MODX Менеджер пакетов (или скопируйте файлы вручную).
2. После установки в базе данных автоматически создаются две таблицы: 
    - `sign3x_documents` — документы
    - `sign3x_profiles` — профили подписантов
3. Перейдите в **Системные настройки → Пространство имён: sign3x** и настройте параметры (см. раздел Системные настройки).
4. **Обязательно** создайте профили подписантов во вкладке «Сотрудники» для всех пользователей, которые должны иметь право подписи.

> **Права доступа.** Панель управления Sign3x доступна только пользователям, прошедшим авторизацию в менеджере MODX (`mgr`). Право подписи дополнительно ограничивается группами пользователей через настройку `sign3x_allowed_groups`.

## 3. Системные настройки

Все настройки находятся в пространстве имён **sign3x**. Откройте: *Администрирование → Системные настройки → фильтр «sign3x»*.

### Основные

<table id="bkmrk-%D0%9A%D0%BB%D1%8E%D1%87-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8-%D0%9F%D0%BE-%D1%83%D0%BC"><thead><tr><th>Ключ настройки</th><th>По умолчанию</th><th>Описание</th></tr></thead><tbody><tr><td>`sign3x_allowed_groups`</td><td>*(пусто)*</td><td>ID групп пользователей с правом подписи. Несколько значений через запятую: `1,5,12`. Sudo-пользователи проверку группы не проходят — им достаточно иметь профиль подписанта.</td></tr><tr><td>`sign3x_secret_salt`</td><td>*(пусто)*</td><td>**Секретная соль** для формирования SHA-256 хэш-ключа. Задайте произвольную сложную строку. *Никогда не меняйте после первого подписания* — это делает существующие хэш-ключи невалидными.</td></tr><tr><td>`sign3x_upload_dir`</td><td>`assets/sign3x/uploads/`</td><td>Директория загрузки PDF-файлов относительно корня сайта. Должна быть доступна для записи веб-сервером.</td></tr><tr><td>`sign3x_filename_mode`</td><td>`translit`</td><td>Формирование имени файла: `translit` — транслитерация, `original` — исходное имя, `unique` — уникальный UUID.</td></tr><tr><td>`sign3x_delete_files`</td><td>`Да`</td><td>Удалять физические PDF-файлы при удалении документа из системы.</td></tr><tr><td>`sign3x_frontend_css`</td><td>`assets/components/sign3x/css/frontend.css`</td><td>URL встроенных фронтенд-стилей. Если поле **пустое** — стили не подключаются.</td></tr></tbody></table>

### Визуальный PDF-штамп

<table id="bkmrk-%D0%9A%D0%BB%D1%8E%D1%87-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8-%D0%9F%D0%BE-%D1%83%D0%BC-1"><thead><tr><th>Ключ настройки</th><th>По умолчанию</th><th>Описание</th></tr></thead><tbody><tr><td>`sign3x_pdf_stamp`</td><td>`Нет`</td><td>Включить добавление визуального штампа в PDF при подписании.</td></tr><tr><td>`sign3x_pdf_stamp_mode`</td><td>`overlay`</td><td>Режим: `overlay` — поверх последней страницы, `newpage` — отдельная страница «Лист ЭЦП».</td></tr><tr><td>`sign3x_stamp_title`</td><td>ЭЛЕКТРОННАЯ ПОДПИСЬ (ПЭП)</td><td>Заголовок штампа (оба режима).</td></tr><tr><td>`sign3x_stamp_page_title`</td><td>ЛИСТ ЭЛЕКТРОННОЙ ПОДПИСИ</td><td>Заголовок страницы подписи (`newpage`).</td></tr><tr><td>`sign3x_stamp_hash_label`</td><td>Программный ключ (SHA-256):</td><td>Подпись над хэш-ключом (`newpage`).</td></tr><tr><td>`sign3x_stamp_law_text`</td><td>*Текст о соответствии ФЗ № 63-ФЗ*</td><td>Текст о соответствии законодательству внутри рамки (`newpage`).</td></tr><tr><td>`sign3x_stamp_verify_text`</td><td>*Текст о верификации*</td><td>Текст под рамкой (`newpage`).</td></tr><tr><td>`sign3x_stamp_footer_text`</td><td>Сформировано автоматически системой Sign3x</td><td>Нижний колонтитул страницы (`newpage`).</td></tr></tbody></table>

## 4. Администрирование

Панель управления Sign3x открывается через меню: *Дополнения → Sign3x*. Интерфейс состоит из двух вкладок.

### 4.1. Вкладка «Сотрудники»

Здесь управляются **профили подписантов** — записи, связывающие пользователя MODX с его ФИО и должностью.

<table id="bkmrk-%D0%9F%D0%BE%D0%BB%D0%B5-%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE"><thead><tr><th>Поле</th><th>Описание</th></tr></thead><tbody><tr><td>Пользователь MODX</td><td>Привязанный аккаунт из пользователей менеджера</td></tr><tr><td>ФИО</td><td>Полное имя подписанта (фиксируется в подписи)</td></tr><tr><td>Должность</td><td>Должность подписанта (фиксируется в подписи)</td></tr></tbody></table>

> **Важно:** Пользователь должен одновременно иметь *профиль подписанта* и входить в одну из групп, указанных в `sign3x_allowed_groups`. При отсутствии хотя бы одного условия кнопка «Подписать» не отображается. Исключение — пользователи с флагом **sudo**: для них проверка членства в группе пропускается.

### 4.2. Вкладка «Документы»

Таблица всех загруженных документов с поиском, пагинацией и цветовой индикацией.

- **Серая строка** — черновик (status = 0, не подписан)
- **Зелёная строка** — подписан (status = 1)

**Поиск** выполняется по: названию документа, ФИО подписанта, хэш-ключу.

<table id="bkmrk-%D0%9A%D0%BD%D0%BE%D0%BF%D0%BA%D0%B0-%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-%D0%A3%D1%81%D0%BB%D0%BE"><thead><tr><th>Кнопка</th><th>Описание</th><th>Условие</th></tr></thead><tbody><tr><td>Загрузить документ</td><td>Загружает PDF-файл и создаёт документ со статусом «Черновик»</td><td>Всегда доступна</td></tr><tr><td>Подписать</td><td>Открывает диалог подтверждения подписи</td><td>Только черновики + наличие права подписи у текущего пользователя</td></tr><tr><td>Удалить</td><td>Удаляет документ из БД (и файл, если включена настройка)</td><td>Всегда доступна; требует подтверждения</td></tr></tbody></table>

### 4.3. Процесс подписания

1. Нажмите кнопку **«Подписать»** рядом с нужным документом.
2. В модальном окне отобразится: 
    - Название документа и ссылка для предпросмотра PDF
    - Ваши ФИО, должность и дата/время подписания
    - Предупреждение о необратимости действия
3. Нажмите **«Подтвердить»**. Система: 
    - Фиксирует ФИО, должность и точное время подписания в базе данных
    - Генерирует уникальный SHA-256 хэш-ключ
    - Устанавливает статус документа = «Подписан»
    - Если включён PDF-штамп — добавляет визуальный штамп в файл

> Подписание **необратимо**. Подписанный документ нельзя перевести обратно в статус «Черновик» средствами интерфейса.

## 5. Сниппет Sign3x

Сниппет выводит **подписанные** документы (status = 1) на страницах сайта с пиктограммой электронной подписи и информацией о подписанте.

### 5.1. Параметры сниппета

<table id="bkmrk-%D0%9F%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80-%D0%A2%D0%B8%D0%BF-%D0%9F%D0%BE-%D1%83%D0%BC%D0%BE%D0%BB"><thead><tr><th>Параметр</th><th>Тип</th><th>По умолчанию</th><th>Описание</th></tr></thead><tbody><tr><td>`&id`</td><td>int</td><td>*не задан*</td><td>ID конкретного документа. Если задан — выводит только этот документ.</td></tr><tr><td>`&limit`</td><td>int</td><td>`20`</td><td>Максимальное количество документов. Сортировка по дате подписания (новые первые).</td></tr><tr><td>`&tpl`</td><td>string</td><td>`sign3x.doc.default`</td><td>Шаблон для одного документа: имя чанка или inline Fenom (`@INLINE {$name}`, требует `&fenom=`1``).</td></tr><tr><td>`&fenom`</td><td>0 / 1</td><td>`0`</td><td>Обрабатывать шаблон через Fenom (pdoTools). При `1` используется синтаксис `{$placeholder}`.</td></tr></tbody></table>

### Плейсхолдеры в шаблонах

<table id="bkmrk-%D0%9F%D0%BB%D0%B5%D0%B9%D1%81%D1%85%D0%BE%D0%BB%D0%B4%D0%B5%D1%80-%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5"><thead><tr><th>Плейсхолдер</th><th>Описание</th></tr></thead><tbody><tr><td>`id`</td><td>ID документа</td></tr><tr><td>`name`</td><td>Название документа (HTML-экранировано)</td></tr><tr><td>`file_url`</td><td>Полный URL до PDF-файла</td></tr><tr><td>`file_path`</td><td>Путь к файлу относительно корня сайта</td></tr><tr><td>`signer_fio`</td><td>ФИО подписанта</td></tr><tr><td>`signer_position`</td><td>Должность подписанта</td></tr><tr><td>`signed_at`</td><td>Дата и время подписания (дд.мм.гггг чч:мм:сс)</td></tr><tr><td>`hash_key`</td><td>SHA-256 хэш-ключ подписи</td></tr><tr><td>`aria_label`</td><td>Полный ARIA-текст для пиктограммы (доступность)</td></tr><tr><td>`assets_url`</td><td>URL директории `assets/` — для ссылок на иконки SVG</td></tr></tbody></table>

### 5.2. Примеры вызова

```
<!-- Вывод последних 20 подписанных документов, дефолтный шаблон -->
[[!Sign3x]]

<!-- С лимитом -->
[[!Sign3x? &limit=`5`]]

<!-- Один конкретный документ -->
[[!Sign3x? &id=`3`]]

<!-- Свой чанк (MODX-синтаксис) -->
[[!Sign3x? &tpl=`sign3x.doc.bs5`]]

<!-- Свой чанк (Fenom-синтаксис, требует pdoTools) -->
[[!Sign3x? &tpl=`sign3x.doc.bs5.fenom` &fenom=`1`]]

<!-- Inline Fenom-шаблон -->
[[!Sign3x? &tpl=`@INLINE <a href="{$file_url}">{$name}</a>` &fenom=`1`]]
```

## 6. Готовые чанки

Компонент поставляется с шестью готовыми чанками-шаблонами:

<table id="bkmrk-%D0%A7%D0%B0%D0%BD%D0%BA-css-%D1%84%D1%80%D0%B5%D0%B9%D0%BC%D0%B2%D0%BE%D1%80%D0%BA-%D0%A1"><thead><tr><th>Чанк</th><th>CSS-фреймворк</th><th>Синтаксис</th><th>Примечание</th></tr></thead><tbody><tr><td>`sign3x.doc.default`</td><td>Встроенный (frontend.css)</td><td>MODX `[[+]]`</td><td>Чанк по умолчанию</td></tr><tr><td>`sign3x.doc.default.fenom`</td><td>Встроенный (frontend.css)</td><td>Fenom `{$}`</td><td>Требует pdoTools</td></tr><tr><td>`sign3x.doc.bs5`</td><td>Bootstrap 5</td><td>MODX `[[+]]`</td><td>—</td></tr><tr><td>`sign3x.doc.bs5.fenom`</td><td>Bootstrap 5</td><td>Fenom `{$}`</td><td>Требует pdoTools</td></tr><tr><td>`sign3x.doc.uikit3`</td><td>UIKit 3</td><td>MODX `[[+]]`</td><td>—</td></tr><tr><td>`sign3x.doc.uikit3.fenom`</td><td>UIKit 3</td><td>Fenom `{$}`</td><td>Требует pdoTools</td></tr></tbody></table>

Все чанки доступны для редактирования через *Элементы → Чанки*. Содержат: SVG-иконку подписи, всплывающую подсказку с ФИО/должностью/датой/хэшем, ссылку на PDF и ARIA-атрибуты для доступности.

## 7. Fenom-шаблоны

Fenom — движок шаблонов с синтаксисом `{$var}` и условиями `{if}...{/if}`, предоставляемый компонентом **pdoTools**. Не зависит от настройки MODX «Разрешить Fenom на страницах».

> **Когда использовать Fenom-чанки:** когда нужна логика в шаблоне — условный вывод полей, циклы. Например, показывать должность только если она задана.

### Сравнение синтаксиса

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-modx-%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8"><thead><tr><th>Задача</th><th>MODX-синтаксис</th><th>Fenom-синтаксис</th></tr></thead><tbody><tr><td>Вывод переменной</td><td>`[[+name]]`</td><td>`{$name}`</td></tr><tr><td>Условный блок</td><td>—</td><td>`{if $signer_position}...{/if}`</td></tr><tr><td>Экранирование</td><td>Выполнено в PHP</td><td>Выполнено в PHP</td></tr></tbody></table>

Пример Fenom-чанка с условием:

```
<div class="sign3x-document">
  <span class="sign3x-stamp" aria-label="{$aria_label}">
    <img src="{$assets_url}components/sign3x/img/sign3x.svg" width="32" height="32" alt="">
  </span>
  <a href="{$file_url}">{$name}</a>
  {if $signer_position}
    <small>{$signer_position}</small>
  {/if}
</div>
```

Вызов сниппета с Fenom-чанком:

```
[[!Sign3x? &tpl=`sign3x.doc.default.fenom` &fenom=`1`]]
```

## 8. CSS и стили

Встроенные стили подключаются автоматически, если настройка `sign3x_frontend_css` не пуста. Чтобы **отключить встроенные стили** и использовать свой CSS — очистите настройку `sign3x_frontend_css`.

### Ключевые CSS-классы

<table id="bkmrk-%D0%9A%D0%BB%D0%B0%D1%81%D1%81-%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-.sign"><thead><tr><th>Класс</th><th>Описание</th></tr></thead><tbody><tr><td>`.sign3x-list`</td><td>Обёртка при дефолтном шаблоне: вертикальный flex-список с отступами</td></tr><tr><td>`.sign3x-document`</td><td>Один документ: flex-строка (иконка + ссылка)</td></tr><tr><td>`.sign3x-stamp`</td><td>Элемент-триггер иконки с всплывающей подсказкой</td></tr><tr><td>`.sign3x-stamp-icon`</td><td>SVG-иконка электронной подписи</td></tr><tr><td>`.sign3x-stamp-tooltip`</td><td>Всплывающая подсказка с данными подписи</td></tr><tr><td>`.sign3x-stamp-key`</td><td>Хэш-ключ (моноширинный шрифт, авто-перенос)</td></tr><tr><td>`.sign3x-doc-link`</td><td>Ссылка на PDF-документ</td></tr></tbody></table>

## 9. Визуальный штамп в PDF

При включённой настройке `sign3x_pdf_stamp` после подписания в PDF-файл добавляется визуальный штамп. Библиотеки **FPDI** и **TCPDF** входят в состав пакета.

### Режимы штампа

<table id="bkmrk-%D0%A0%D0%B5%D0%B6%D0%B8%D0%BC-%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-overl"><thead><tr><th>Режим</th><th>Описание</th></tr></thead><tbody><tr><td>`overlay`</td><td>Синий прямоугольный штамп поверх последней страницы документа (правый нижний угол)</td></tr><tr><td>`newpage`</td><td>Отдельная страница «Лист электронной подписи» добавляется в конец документа</td></tr></tbody></table>

При успешном создании штампа оригинальный файл заменяется подписанной версией, путь обновляется в базе данных. При ошибке документ сохраняется без штампа — ошибка логируется в журнал MODX.

> Все тексты в штампе настраиваются через системные настройки группы `sign3x_stamp_*`.

## 10. Верификация подписи

Каждая подпись сопровождается уникальным SHA-256 хэш-ключом. Хэш формируется из следующих данных:

```
SHA-256(id|name|file_path|fio|position|signed_at|salt)
```

<table id="bkmrk-%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82-%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-i"><thead><tr><th>Компонент</th><th>Значение</th></tr></thead><tbody><tr><td>`id`</td><td>ID документа в базе данных</td></tr><tr><td>`name`</td><td>Название документа</td></tr><tr><td>`file_path`</td><td>Путь к файлу на момент подписания</td></tr><tr><td>`fio`</td><td>ФИО подписанта из профиля</td></tr><tr><td>`position`</td><td>Должность подписанта из профиля</td></tr><tr><td>`signed_at`</td><td>Точная дата/время подписания (MySQL datetime)</td></tr><tr><td>`salt`</td><td>Секретная соль из настройки `sign3x_secret_salt`</td></tr></tbody></table>

Хэш-ключ отображается:

- В таблице документов (вкладка «Документы»)
- В tooltip-подсказке на сайте при наведении на иконку подписи
- В PDF-штампе (если включён)

> **Не изменяйте `sign3x_secret_salt`** после первого подписания. Изменение соли сделает невозможным воспроизведение хэш-ключей и фактически аннулирует проверяемость всех существующих подписей.