3359a8db13
Модель/сервисы HR-заявок с заменами, приглашения на установку пароля (инвайты), обновлённая страница профиля сотрудника и правки 2FA. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
114 lines
8.0 KiB
HTML
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>
|