Files
ACORE/templates/partials/employee-profile-2fa.html
T
lokses 3359a8db13 employees: HR-заявки, приглашения на пароль, профиль и 2FA
Модель/сервисы HR-заявок с заменами, приглашения на установку пароля
(инвайты), обновлённая страница профиля сотрудника и правки 2FA.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 18:03:32 +03:00

114 lines
8.0 KiB
HTML

{% load i18n %}
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); padding:1.5rem; height:100%;">
<h3 style="font-weight:600; font-size:0.9375rem; margin-bottom:0.5rem;">{% trans "Двухфакторная аутентификация (2FA)" %}</h3>
<p style="font-size:0.8125rem; color:var(--color-muted-foreground); margin-bottom:1rem;">
{% if twofa_mandatory %}
{% trans "Для вашего аккаунта 2FA обязательна." %}
{% else %}
{% trans "Дополнительная защита входа через приложение-аутентификатор." %}
{% endif %}
</p>
{% if twofa_message %}
<div style="margin-bottom:1rem; color:#166534; background:rgba(34,197,94,0.12); border:1px solid rgba(34,197,94,0.35); padding:0.75rem; border-radius:0.5rem; font-size:0.875rem;">{{ twofa_message }}</div>
{% endif %}
{% if twofa_error %}
<div style="margin-bottom:1rem; color:#d63333; background:rgba(214,51,51,0.1); border:1px solid rgba(214,51,51,0.25); padding:0.75rem; border-radius:0.5rem; font-size:0.875rem;">{{ twofa_error }}</div>
{% endif %}
<div style="display:flex; align-items:center; gap:0.75rem; margin-bottom:1rem; flex-wrap:wrap;">
<span style="font-size:0.8125rem; color:var(--color-muted-foreground);">{% trans "Статус" %}</span>
{% if twofa_enabled %}
<span class="badge badge-success">{% trans "Включена" %}</span>
{% else %}
<span class="badge badge-muted">{% trans "Выключена" %}</span>
{% endif %}
{% if twofa_enabled %}
<span style="font-size:0.75rem; color:var(--color-muted-foreground);">
{% blocktrans count counter=twofa_backup_remaining %}Осталось {{ counter }} резервный код{% plural %}Осталось {{ counter }} резервных кодов{% endblocktrans %}
</span>
{% endif %}
</div>
{% if twofa_backup_codes %}
<div style="margin-bottom:1rem; padding:1rem; background:var(--color-muted); border:1px solid var(--color-border); border-radius:0.5rem;">
<p style="font-size:0.8125rem; font-weight:500; margin-bottom:0.75rem;">{% trans "Резервные коды (сохраните сейчас — больше не будут показаны)" %}</p>
<div style="display:grid; grid-template-columns:repeat(auto-fill, minmax(9rem, 1fr)); gap:0.5rem;">
{% for code in twofa_backup_codes %}
<code style="display:block; padding:0.5rem; background:var(--color-card); border:1px solid var(--color-border); border-radius:0.375rem; font-family:ui-monospace, monospace; font-size:0.75rem; text-align:center;">{{ code }}</code>
{% endfor %}
</div>
</div>
{% endif %}
{% if twofa_show_setup %}
<div style="border-top:1px solid var(--color-border); padding-top:1rem;">
{% if twofa_reset_notice %}
<div style="margin-bottom:1rem; color:#856404; background:rgba(255,193,7,0.15); border:1px solid rgba(255,193,7,0.35); padding:0.75rem; border-radius:0.5rem; font-size:0.875rem;">{{ twofa_reset_notice }}</div>
{% endif %}
{% if twofa_setup_error %}
<div style="margin-bottom:1rem; color:#d63333; background:rgba(214,51,51,0.1); border:1px solid rgba(214,51,51,0.25); padding:0.75rem; border-radius:0.5rem; font-size:0.875rem;">{{ twofa_setup_error }}</div>
{% endif %}
<div style="display:grid; grid-template-columns:1fr auto; gap:1.25rem; align-items:start;">
<div>
<div style="margin-bottom:1rem;">
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-bottom:0.25rem;">{% trans "Ключ вручную:" %}</div>
<code style="font-size:0.8125rem; font-weight:600; letter-spacing:0.05em; word-break:break-all;">{{ twofa_setup_secret }}</code>
</div>
<form hx-post="/2fa/setup/" hx-target="#main-content" hx-indicator="#loader">
{% csrf_token %}
<input type="hidden" name="return_to" value="profile">
<label style="display:block; font-size:0.8125rem; font-weight:500; margin-bottom:0.375rem;">{% trans "Код из приложения (6 цифр)" %}</label>
<input type="text" name="code" inputmode="numeric" autocomplete="one-time-code" maxlength="6" required
class="input" style="width:100%; max-width:12rem; text-align:center; letter-spacing:0.3em; margin-bottom:1rem;">
<div style="display:flex; gap:0.5rem; flex-wrap:wrap;">
<button type="submit" class="btn btn-primary">{% trans "Включить 2FA" %}</button>
<button type="button" class="btn btn-secondary"
hx-get="/employees/{{ employee.pk }}/?tab=settings"
hx-target="#main-content" hx-push-url="/employees/{{ employee.pk }}/?tab=settings"
hx-indicator="#loader">{% trans "Отмена" %}</button>
</div>
</form>
</div>
<div style="text-align:center;">
<img src="{{ twofa_setup_qr }}" alt="QR" style="width:160px; height:160px; border:1px solid var(--color-border); border-radius:0.5rem;">
</div>
</div>
</div>
{% elif not twofa_enabled %}
<button type="button" class="btn btn-primary"
hx-get="/2fa/setup/?return_to=profile"
hx-target="#main-content" hx-indicator="#loader">
{% trans "Настроить 2FA" %}
</button>
{% else %}
<div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); gap:1rem; border-top:1px solid var(--color-border); padding-top:1rem;">
<form hx-post="/2fa/regenerate-backup/" hx-target="#main-content" hx-indicator="#loader">
{% csrf_token %}
<p style="font-size:0.8125rem; color:var(--color-muted-foreground); margin-bottom:0.75rem;">{% trans "Новые резервные коды (старые перестанут работать)." %}</p>
<label style="display:block; font-size:0.8125rem; font-weight:500; margin-bottom:0.375rem;">{% trans "Код из приложения" %}</label>
<input type="text" name="code" inputmode="numeric" autocomplete="one-time-code" maxlength="6" required
class="input" style="width:100%; max-width:12rem; text-align:center; letter-spacing:0.3em; margin-bottom:0.75rem;">
<button type="submit" class="btn btn-secondary">{% trans "Новые резервные коды" %}</button>
</form>
{% if twofa_can_disable %}
<form hx-post="/2fa/disable/" hx-target="#main-content" hx-indicator="#loader"
hx-confirm="{% trans 'Отключить 2FA? Вход будет только по паролю.' %}">
{% csrf_token %}
<p style="font-size:0.8125rem; color:var(--color-muted-foreground); margin-bottom:0.75rem;">{% trans "Отключить двухфакторную аутентификацию." %}</p>
<label style="display:block; font-size:0.8125rem; font-weight:500; margin-bottom:0.375rem;">{% trans "Код из приложения" %}</label>
<input type="text" name="code" inputmode="numeric" autocomplete="one-time-code" maxlength="6" required
class="input" style="width:100%; max-width:12rem; text-align:center; letter-spacing:0.3em; margin-bottom:0.75rem;">
<button type="submit" class="btn btn-secondary" style="color:var(--color-destructive, #d63333);">{% trans "Отключить 2FA" %}</button>
</form>
{% elif twofa_mandatory %}
<p style="font-size:0.8125rem; color:var(--color-muted-foreground); margin:0; align-self:center;">{% trans "Отключение недоступно — 2FA обязательна для вашего аккаунта." %}</p>
{% endif %}
</div>
{% endif %}
</div>