feat: живой цикл M2M с НРД + мастер установки ключа на флешку
Инфраструктура M2M (живой обмен с НРД через ИШ): - обработка M2MTransferResponse: ERROR(M2Mxx) → заявка Отклонена, сохранение ответа; INFO → ждём Decision; идемпотентность поллера - fallback-корреляция ответов с нулевым GUID (M2M14/M2M17) по FIFO - сырой XML ответа НРД в карточке заявки (для пересылки в ТП) - тестовый пакет роботу приведён к эталону m2m_robot_samples (CostInfo=Yes, 4 бумаги, IsolationStatus, DocumentSeries=сценарий); override паспорта - редирект из теста сразу в карточку заявки Мастер установки ключа Валидаты на флешку (admin/setup/keywizard): - пошаговый: загрузка .7z+пароль → выбор флешки → запись → справочник сертификатов (CRL) → перезапуск+проверка ИШ → готово - привилегированный воркер (bj-keymedia) в host-namespace через файл-обмен, bj-server остаётся в песочнице - сохранение структуры профиля архива (spr<N>), перечисление съёмных USB Прочее: - пакет-доказательство для ТП НРД + форма регистрации участника M2M - эталонные образцы робота (DOC/m2m_robot_samples) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
{{define "content"}}
|
||||
{{/* Пошаговый мастер установки ключа Валидаты на флешку. */}}
|
||||
|
||||
<div class="hero">
|
||||
<h1 class="hero-greeting">Установка ключа на флешку</h1>
|
||||
<span class="hero-status">Загрузите архив НРД → запись на носитель → справочник сертификатов → проверка → готово</span>
|
||||
</div>
|
||||
|
||||
{{$s := .State}}
|
||||
|
||||
{{/* ===== Лента шагов ===== */}}
|
||||
<div class="card">
|
||||
<ol style="list-style:none;padding:0;margin:0;display:grid;gap:12px">
|
||||
{{range $i, $step := $s.Steps}}
|
||||
<li style="display:flex;gap:12px;align-items:flex-start">
|
||||
<span style="flex:0 0 28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;
|
||||
{{if eq $step.Status "ok"}}background:var(--ok-weak);color:var(--ok)
|
||||
{{else if eq $step.Status "error"}}background:var(--err-weak);color:var(--err)
|
||||
{{else if eq $step.Status "active"}}background:var(--accent-weak);color:var(--accent)
|
||||
{{else}}background:var(--surface-2,#eee);color:var(--muted,#999){{end}}">
|
||||
{{if eq $step.Status "ok"}}✓{{else if eq $step.Status "error"}}✕{{else}}{{add $i 1}}{{end}}
|
||||
</span>
|
||||
<div style="flex:1">
|
||||
<div style="font-weight:600">{{$step.Title}}</div>
|
||||
{{if $step.Detail}}<div class="muted" style="font-size:13px;margin-top:2px">{{$step.Detail}}</div>{{end}}
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{{/* ===== Действие в зависимости от состояния ===== */}}
|
||||
{{if $s.Done}}
|
||||
<div class="card" style="border-left:3px solid var(--ok)">
|
||||
<h2>✓ Готово</h2>
|
||||
<p>Ключ установлен на флешку, справочник сертификатов сформирован, Валидата проверена.</p>
|
||||
{{if $s.Backup}}<p class="muted">Бэкап прежнего носителя: <code>{{$s.Backup}}</code></p>{{end}}
|
||||
<div style="display:flex;gap:8px;margin-top:12px;flex-wrap:wrap">
|
||||
<form method="post" action="/admin/setup/test-nsd" style="margin:0">
|
||||
<input type="hidden" name="scenario" value="2001">
|
||||
<button type="submit" class="btn btn-ok">→ Отправить тестовый документ роботу</button>
|
||||
</form>
|
||||
<form method="post" action="/admin/setup/keywizard/reset" style="margin:0">
|
||||
<button type="submit" class="btn btn-secondary">Установить ещё один ключ</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{else if $s.StagingID}}
|
||||
{{/* Архив загружен — выбор флешки + запись */}}
|
||||
<div class="card">
|
||||
<h2>Шаг 2 — выбор флешки и запись</h2>
|
||||
<p class="muted">Архив распакован. Ключ: <code>{{fallbackTpl $s.VDK "—"}}</code>.
|
||||
Выберите носитель — запись сделает бэкап, запишет ключ и справочник
|
||||
сертификатов, дотянет CRL и перезапустит ИШ.</p>
|
||||
<form method="post" action="/admin/setup/keywizard/install" style="margin-top:12px;display:grid;gap:12px;max-width:640px"
|
||||
onsubmit="this.querySelector('button[type=submit]').disabled=true;this.querySelector('button[type=submit]').textContent='Устанавливаю…';">
|
||||
|
||||
<div>
|
||||
<label style="font-weight:600;display:block;margin-bottom:6px">Целевая флешка</label>
|
||||
{{if .Drives}}
|
||||
{{range $i, $d := .Drives}}
|
||||
<label style="display:flex;gap:10px;align-items:flex-start;padding:10px;border:1px solid var(--border,#ddd);border-radius:8px;margin-bottom:8px;cursor:pointer">
|
||||
<input type="radio" name="target_device" value="{{$d.Device}}" {{if $d.IsKeymedia}}checked{{else if and (eq $i 0) (not (anyKeymedia $.Drives))}}checked{{end}} style="margin-top:3px">
|
||||
<span>
|
||||
<b>{{fallbackTpl $d.Model "USB-носитель"}}</b> · {{$d.Size}} · {{$d.FSType}}
|
||||
{{if $d.Label}}· метка «{{$d.Label}}»{{end}}<br>
|
||||
<span class="muted" style="font-size:12px">{{$d.Device}}{{if $d.Mountpoint}} · {{$d.Mountpoint}}{{end}}
|
||||
{{if $d.IsKeymedia}}<b style="color:var(--accent)">← текущий ключевой носитель ИШ (рекомендуется)</b>{{end}}</span>
|
||||
</span>
|
||||
</label>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<p class="muted">Съёмные носители не обнаружены — будет использован текущий ключевой носитель ИШ по умолчанию.</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style="font-weight:600;display:block;margin-bottom:6px">Имя профиля в справочнике (необязательно)</label>
|
||||
<input type="text" name="profile_name" placeholder="Авто из архива (напр. PrUser1046)" autocomplete="off"
|
||||
pattern="[A-Za-z0-9_-]*" style="width:100%">
|
||||
<span class="muted" style="font-size:12px">Пусто = имя берётся из архива автоматически.</span>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-ok">Записать на флешку, сформировать справочник и проверить ИШ</button>
|
||||
</form>
|
||||
<form method="post" action="/admin/setup/keywizard/reset" style="margin-top:8px">
|
||||
<button type="submit" class="btn btn-secondary">Отмена / загрузить другой архив</button>
|
||||
</form>
|
||||
</div>
|
||||
{{else}}
|
||||
{{/* Начало — форма загрузки */}}
|
||||
<div class="card">
|
||||
<h2>Шаг 1 — загрузка архива</h2>
|
||||
<p class="muted">Выберите .7z-архив с ключом от НРД и введите пароль архива.</p>
|
||||
<form method="post" action="/admin/setup/keywizard/upload" enctype="multipart/form-data"
|
||||
style="margin-top:12px;display:grid;gap:10px;max-width:560px">
|
||||
<input type="file" name="archive" accept=".7z,.zip" required>
|
||||
<input type="password" name="password" placeholder="Пароль архива (например 11)" autocomplete="off">
|
||||
<button type="submit" class="btn btn-ok">Загрузить и распаковать</button>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<p style="margin-top:16px"><a href="/admin/setup" class="muted">← Назад к настройкам</a></p>
|
||||
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user