- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
112 lines
4.4 KiB
HTML
112 lines
4.4 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Смена пароля - DevOpsLab{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="login-container">
|
|
<div class="login-card">
|
|
<div class="card-header">
|
|
<i class="fas fa-key fa-3x mb-3"></i>
|
|
<h1>Смена пароля</h1>
|
|
<p class="text-muted">Измените пароль для пользователя {{ current_user.username }}</p>
|
|
</div>
|
|
<div class="card-body">
|
|
<form
|
|
hx-post="/api/v1/auth/change-password"
|
|
hx-target="#change-password-result"
|
|
hx-swap="innerHTML"
|
|
class="login-form"
|
|
>
|
|
<div class="form-group">
|
|
<label class="form-label">Текущий пароль</label>
|
|
<input
|
|
type="password"
|
|
name="current_password"
|
|
class="form-control"
|
|
placeholder="••••••••"
|
|
required
|
|
autofocus
|
|
>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Новый пароль</label>
|
|
<input
|
|
type="password"
|
|
name="new_password"
|
|
class="form-control"
|
|
placeholder="••••••••"
|
|
required
|
|
minlength="6"
|
|
>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Подтвердите новый пароль</label>
|
|
<input
|
|
type="password"
|
|
name="new_password_confirm"
|
|
class="form-control"
|
|
placeholder="••••••••"
|
|
required
|
|
minlength="6"
|
|
>
|
|
</div>
|
|
|
|
<div id="change-password-result" class="mt-3"></div>
|
|
|
|
<button type="submit" class="btn btn-primary w-100">
|
|
<i class="fas fa-save me-2"></i>
|
|
Изменить пароль
|
|
</button>
|
|
</form>
|
|
|
|
<div class="mt-4 text-center">
|
|
<a href="/" class="btn btn-link">
|
|
<i class="fas fa-arrow-left me-2"></i>
|
|
Назад
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const form = document.querySelector('.login-form');
|
|
const newPassword = form.querySelector('input[name="new_password"]');
|
|
const newPasswordConfirm = form.querySelector('input[name="new_password_confirm"]');
|
|
|
|
// Проверка совпадения паролей
|
|
function validatePasswords() {
|
|
if (newPassword.value !== newPasswordConfirm.value) {
|
|
newPasswordConfirm.setCustomValidity('Пароли не совпадают');
|
|
} else {
|
|
newPasswordConfirm.setCustomValidity('');
|
|
}
|
|
}
|
|
|
|
newPassword.addEventListener('input', validatePasswords);
|
|
newPasswordConfirm.addEventListener('input', validatePasswords);
|
|
|
|
form.addEventListener('htmx:afterRequest', function(event) {
|
|
if (event.detail.xhr.status === 200) {
|
|
const resultDiv = document.getElementById('change-password-result');
|
|
resultDiv.innerHTML = '<div class="alert alert-success mt-3">Пароль успешно изменен</div>';
|
|
setTimeout(() => {
|
|
window.location.href = '/';
|
|
}, 2000);
|
|
} else {
|
|
const resultDiv = document.getElementById('change-password-result');
|
|
try {
|
|
const response = JSON.parse(event.detail.xhr.responseText);
|
|
resultDiv.innerHTML = `<div class="alert alert-danger mt-3">${response.detail || 'Ошибка при смене пароля'}</div>`;
|
|
} catch (e) {
|
|
resultDiv.innerHTML = '<div class="alert alert-danger mt-3">Ошибка при смене пароля</div>';
|
|
}
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|