accounts/mirzaev/site/account/system/views/pages/entry.html

411 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% block css %}
<link type="text/css" rel="stylesheet" href="/css/account.css">
<link type="text/css" rel="stylesheet" href="/css/icons/arrow_right.css">
<link type="text/css" rel="stylesheet" href="/css/icons/nametag.css">
<link type="text/css" rel="stylesheet" href="/css/icons/keyhole.css">
<link type="text/css" rel="stylesheet" href="/css/icons/user_add.css">
{% endblock %}
{% block body %}
<div class="column">
<section id="entry" class="panel medium">
<section class="header unselectable">
<h1>Идентификация</h1>
</section>
<section class="body">
<label id="login">
<i class="nametag"></i>
<input name="login" type="text" placeholder="Входной псевдоним"
value="{{ account.login ?? session.buffer.login ?? cookie.buffer_login }}"
onkeypress="if (event.keyCode === 13) __login()" autofocus>
<button class="accept" onclick="__login()"><i class="arrow right"></i></button>
</label>
<label id="password" class="hidden">
<i class="keyhole"></i>
<input name="password" type="password" placeholder="Пароль" autocomplete="current-password"
onkeypress="if (event.keyCode === 13) __password()">
<button class="accept" onclick="__password()"><i class="arrow right"></i></button>
</label>
<label id="invite" class="hidden">
<i class="user add"></i>
<input name="invite" type="text" placeholder="Ключ приглашения"
onkeypress="if (event.keyCode === 13) __invite()">
<button class="accept" onclick="__invite()"><i class="arrow right"></i></button>
</label>
</section>
</section>
<section id="errors" class="panel medium animation window hidden" style="--height: 300px">
<section class="body">
<dl></dl>
</section>
</section>
</div>
<section id="mnemonic" class="panel small hidden">
<section class="header unselectable">
<h2>Мнемонические</h2>
</section>
<section class="body">
<ul></ul>
</section>
</section>
<section id="classic" class="panel small hidden">
<section class="header unselectable">
<h2>Классические</h2>
</section>
<section class="body">
<ul></ul>
</section>
</section>
<script>
// Инициализация функций в глобальной области видимости
let _login, __login, _password, __password, _invite, __invite, _errors;
document.addEventListener('damper.initialized', function (e) {
// Инициализирован демпфер
// Инициализация HTML-элемента с блоком входа в аккаунт
const entry = {wrap: document.getElementById('entry')};
entry.title = entry.wrap.getElementsByTagName('h1')[0];
// Инициализация HTML-элемента с блоком мнемонических паролей
const mnemonic = {wrap: document.getElementById('mnemonic')};
mnemonic.list = mnemonic.wrap.getElementsByTagName('ul')[0];
// Инициализация HTML-элемента с блоком классических паролей
const classic = {wrap: document.getElementById('classic')};
classic.list = classic.wrap.getElementsByTagName('ul')[0];
// Инициализация HTML-элемента с блоком ошибок
const errors = {wrap: document.getElementById('errors')};
errors.list = errors.wrap.getElementsByTagName('dl')[0];
// Инициализация HTML-элементов-оболочек полей ввода
const labels = {
login: {label: document.getElementById('login')},
password: {label: document.getElementById('password')},
invite: {label: document.getElementById('invite')}
};
labels.login.input = labels.login.label.querySelector('input[name=login]');
labels.password.input = labels.password.label.querySelector('input[name=password]');
labels.invite.input = labels.invite.label.querySelector('input[name=invite]');
/**
* Отправить входной псевдоним на сервер
*
* @return {void}
*/
_login = e.detail.damper(async () => {
// Деинициализация индикатора и анимации об ошибке
labels.login.input.classList.remove('error');
// Запрос к серверу
const response = await session.login(labels.login.input.value);
if (_errors(response.errors)) {
// Сгенерированы ошибки
// Разлокировка поля ввода
labels.login.input.disabled = false;;
// Инициализация отображения ошибки
labels.login.input.classList.add('error');
// Фокусировка на поле ввода
labels.login.input.focus();
} else {
// Не сгенерированы ошибки (подразумевается их отсутствие)
if (typeof response.exist === 'boolean')
if (response.exist) {
// Найден аккаунт
// Инициализация интерфейса аутентификации
entry.title.innerText = 'Аутентификация';
labels.login.label.classList.add('hidden');
labels.password.label.classList.remove('hidden');
labels.password.input.focus();
} else {
// Не найден аккаунт
// Инициализация интерфейса регистрации
entry.title.innerText = 'Регистрация';
labels.login.label.classList.add('hidden');
labels.invite.label.classList.remove('hidden');
labels.invite.input.focus();
}
}
}, 500);
/**
* Отправить входной псевдоним на сервер с дополнительной подготовкой
*
* @return {void}
*/
__login = () => {
// Блокировка поля ввода
labels.login.input.disabled = true;
// Реинициализация блока ошибок
_errors();
// Запуск процесса отправки входного псевдонима
_login();
}
/**
* Отправить пароль на сервер
*
* @return {void}
*/
_password = e.detail.damper(async () => {
// Деинициализация индикатора и анимации об ошибке
labels.password.input.classList.remove('error');
// Запрос к серверу
const response = await session.password(labels.password.input.value);
if (_errors(response.errors)) {
// Сгенерированы ошибки
// Разлокировка поля ввода
labels.password.input.disabled = false;
// Инициализация отображения ошибки
labels.password.input.classList.add('error');
// Фокусировка на поле ввода
labels.password.input.focus();
} else {
// Не сгенерированы ошибки (подразумевается их отсутствие)
if (typeof response.verify === 'boolean')
if (response.verify) {
// Пройдена проверка пароля на соответствие требованиям
if (response.account) {
// Инициализирован аккаунт
}
}
}
}, 500);
/**
* Отправить пароль на сервер с дополнительной подготовкой
*
* @return {void}
*/
__password = () => {
// Блокировка поля ввода
labels.password.input.disabled = true;
// Реинициализация блока ошибок
_errors();
// Запуск процесса отправки входного псевдонима
_password();
}
/**
* Отправить код приглашения на сервер
*
* @return {void}
*/
_invite = e.detail.damper(async () => {
// Деинициализация индикатора и анимации об ошибке
labels.invite.input.classList.remove('error');
// Запрос к серверу
const response = await session.invite(labels.invite.input.value);
if (_errors(response.errors)) {
// Сгенерированы ошибки
// Разблокировка поля ввода
labels.invite.input.disabled = false;
// Инициализация отображения ошибки
labels.invite.input.classList.add('error');
// Фокусировка на поле ввода
labels.invite.input.focus();
} else {
// Не сгенерированы ошибки (подразумевается их отсутствие)
if (typeof response.exist === 'boolean')
if (response.exist) {
// Найдено приглашение
// Инициализация интерфейса ввода пароля
labels.invite.label.classList.add('hidden');
labels.password.input.autocomplete = 'new-password';
labels.password.label.classList.remove('hidden');
mnemonic.wrap.classList.remove('hidden');
classic.wrap.classList.remove('hidden');
for (let i = 0; i < 6; i++) {
// Генерация HTML-элементов с примерами мнемонических паролей
// Инициализация HTML-элемента
const element = document.createElement('li');
// Генерация пароля
password.generate(Math.floor(Math.random() * 3) + 2, 'mnemonic')
.then((responce) => {
if (responce.password === '') {
// Не удалось сгенерировать пароль
// Перезапуск итерации
--i;
return;
}
// Запись пароля
element.innerText = responce.password;
// Запись HTML-элемента с паролем в список
mnemonic.list.appendChild(element);
// Генерация списка с текстом ошибок
_errors(response.errors);
});
}
for (let i = 0; i < 8; i++) {
// Генерация HTML-элементов с примерами классических паролей
// Инициализация HTML-элемента
const element = document.createElement('li');
// Генерация пароля
password.generate(Math.floor(Math.random() * 14) + 4)
.then((responce) => {
if (responce.password === '') {
// Не удалось сгенерировать пароль
// Перезапуск итерации
--i;
return;
}
// Запись пароля
element.innerText = responce.password;
// Запись HTML-элемента с паролем в список
classic.list.appendChild(element);
// Генерация списка с текстом ошибок
_errors(response.errors);
});
}
}
}
}, 500);
/**
* Отправить код приглашения на сервер с дополнительной подготовкой
*
* @return {void}
*/
__invite = () => {
// Блокировка поля ввода
labels.invite.input.disabled = true;
// Реинициализация блока ошибок
_errors();
// Запуск процесса отправки входного псевдонима
_invite();
}
/**
* Сгенерировать HTML-элемент с блоком ошибок
*
* @param {object} registry Реестр ошибок
* @param {bool} reinitialization Реинициализировать?
*
* @return {bool} Сгенерированы ошибки?
*/
_errors = (registry, reinitialization = true) => {
function height() {
// Скрытие HTML-элемента
errors.wrap.style.zIndex = '-99999';
errors.wrap.style.left = '-99999px';
errors.wrap.style.top = '-99999px';
errors.wrap.style.position = 'absolute';
errors.wrap.style.display = 'var(--display, unset)';
errors.wrap.style.opacity = '0';
errors.wrap.style.animationName = 'unset';
// Реинициализация переменной с данными о высоте HTML-элемента
errors.wrap.style.setProperty('--height', errors.wrap.offsetHeight + 'px');
// Отмена скрытия HTML-элемента
errors.wrap.style.zIndex =
errors.wrap.style.left =
errors.wrap.style.top =
errors.wrap.style.position =
errors.wrap.style.display =
errors.wrap.style.opacity =
errors.wrap.style.animationName = null;
}
// Удаление ошибок из прошлой генерации
if (reinitialization) errors.list.innerHTML = null;
for (error in registry) {
// Генерация HTML-элементов с текстами ошибок
// Инициализация HTML-элемента
const element = document.createElement('dd');
if (typeof registry[error] === 'object') {
// Категория ошибок
// Проверка наличия ошибок
if (registry[error].length === 0) continue;
// Инициализация HTML-элемента
const element = document.createElement('dt');
// Запись текста категории
element.innerText = error;
// Запись HTML-элемента в список
errors.list.appendChild(element);
// Реинициализация высоты
height();
// Обработка вложенных ошибок (вход в рекурсию)
_errors(registry[error], false);
} else {
// Текст ошибки (подразумевается)
// Запись текста ошибки
element.innerText = registry[error];
// Запись HTML-элемента в список
errors.list.appendChild(element);
// Реинициализация высоты
height();
}
}
// Реинициализация HTML-элемента с текстом ошибок
if (reinitialization && errors.list.childElementCount === 0) errors.wrap.classList.add('hidden');
else errors.wrap.classList.remove('hidden');
return errors.list.childElementCount === 0 ? false : true;
};
});
</script>
{% endblock %}
{% block js %}
<script type="text/javascript" src="/js/session.js"></script>
<script type="text/javascript" src="/js/password.js"></script>
{% endblock %}