generated from mirzaev/pot
	
		
			
				
	
	
		
			248 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| {% 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 %}
 | ||
| <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="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 errors = new Map;
 | ||
| 
 | ||
|   // Инициализация функций в глобальной области видимости
 | ||
|   let _login, _password, _invite
 | ||
|   document.addEventListener('damper.initialized', function (e) {
 | ||
|     // Инициализирован демпфер
 | ||
| 
 | ||
|     // Инициализация узлов
 | ||
|     const entry = document.getElementById('entry');
 | ||
|     const mnemonic = document.getElementById('mnemonic');
 | ||
|     const classic = document.getElementById('classic');
 | ||
| 
 | ||
|     // Инициализация элемента с заголовком
 | ||
|     const title = entry.getElementsByTagName('h1')[0];
 | ||
| 
 | ||
|     // Инициализация элементов-оболочек полей ввода
 | ||
|     const labels = {
 | ||
|       login: document.getElementById('login'),
 | ||
|       invite: document.getElementById('invite'),
 | ||
|       password: document.getElementById('password')
 | ||
|     };
 | ||
| 
 | ||
|     /**
 | ||
|      * Отправить входной псевдоним на сервер
 | ||
|      *
 | ||
|      * @return {void}
 | ||
|      */
 | ||
|     _login = () => {
 | ||
|       // Инициализация поля ввода
 | ||
|       const input = labels.login.querySelector('input[name=login]');
 | ||
| 
 | ||
|       // Блокировка поля ввода
 | ||
|       input.disabled = true;
 | ||
| 
 | ||
|       return e.detail.damper(async () => {
 | ||
|         // Запрос к серверу
 | ||
|         const response = await session.login(input.value, errors);
 | ||
| 
 | ||
|         if (response.exist) {
 | ||
|           // Найден аккаунт
 | ||
| 
 | ||
|           // Инициализация интерфейса аутентификации
 | ||
|           title.innerText = 'Аутентификация';
 | ||
|           labels.login.classList.add('hidden');
 | ||
|           labels.password.classList.remove('hidden');
 | ||
|           labels.password.querySelector('input[name=password]').focus();
 | ||
|         } else {
 | ||
|           // Не найден аккаунт
 | ||
| 
 | ||
|           // Инициализация интерфейса регистрации
 | ||
|           title.innerText = 'Регистрация';
 | ||
|           labels.login.classList.add('hidden');
 | ||
|           labels.invite.classList.remove('hidden');
 | ||
|           labels.invite.querySelector('input[name=invite]').focus();
 | ||
|         }
 | ||
|       }, 1000)();
 | ||
|     };
 | ||
| 
 | ||
|     /**
 | ||
|      * Отправить пароль на сервер
 | ||
|      *
 | ||
|      * @return {void}
 | ||
|      */
 | ||
|     _password = () => {
 | ||
|       // Инициализация поля ввода
 | ||
|       const input = labels.password.querySelector('input[name=password]');
 | ||
| 
 | ||
|       // Блокировка поля ввода
 | ||
|       input.disabled = true;
 | ||
| 
 | ||
|       return e.detail.damper(async () => {
 | ||
|         // Деинициализация индикатора и анимации об ошибке
 | ||
|         input.classList.remove('error');
 | ||
|         
 | ||
|         // Запрос к серверу
 | ||
|         const response = await session.password(input.value, errors);
 | ||
| 
 | ||
|         if (response.verify) {
 | ||
|           // Пройдена проверка пароля на соответствие требованиям
 | ||
| 
 | ||
|         } else {
 | ||
|           // Не пройдена проверка пароля на соответствие требованиям
 | ||
| 
 | ||
|           // Разблокировка поля для ввода
 | ||
|           input.disabled = false;
 | ||
| 
 | ||
|           // Инициализация отображения ошибки
 | ||
|           input.classList.add('error');
 | ||
| 
 | ||
|           // Фокусировка на поле ввода
 | ||
|           input.focus();
 | ||
|         }
 | ||
|       }, 1000)();
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * Отправить код приглашения на сервер
 | ||
|      *
 | ||
|      * @return {void}
 | ||
|      */
 | ||
|     _invite = () => {
 | ||
|       // Инициализация поля ввода
 | ||
|       const input = labels.invite.querySelector('input[name=invite]');
 | ||
| 
 | ||
|       // Блокировка поля ввода
 | ||
|       input.disabled = true;
 | ||
| 
 | ||
|       return e.detail.damper(async () => {
 | ||
|         // Деинициализация индикатора и анимации об ошибке
 | ||
|         input.classList.remove('error');
 | ||
| 
 | ||
|         // Запрос к серверу
 | ||
|         const response = await session.invite(input.value, errors);
 | ||
| 
 | ||
|         if (response.exist) {
 | ||
|           // Найдено приглашение
 | ||
| 
 | ||
|           // Инициализация интерфейса ввода пароля
 | ||
|           labels.invite.classList.add('hidden');
 | ||
|           labels.password.querySelector('input[name=password]').autocomplete = 'new-password';
 | ||
|           labels.password.classList.remove('hidden');
 | ||
|           mnemonic.classList.remove('hidden');
 | ||
|           classic.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.getElementsByTagName('ul')[0].appendChild(element);
 | ||
|               });
 | ||
|           }
 | ||
| 
 | ||
|           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.getElementsByTagName('ul')[0].appendChild(element);
 | ||
|               });
 | ||
|           }
 | ||
|         } else {
 | ||
|           // Не найдено приглашение
 | ||
| 
 | ||
|           // Разблокировка поля для ввода
 | ||
|           input.disabled = false;
 | ||
| 
 | ||
|           // Инициализация отображения ошибки
 | ||
|           input.classList.add('error');
 | ||
| 
 | ||
|           // Фокусировка на поле ввода
 | ||
|           input.focus();
 | ||
|         }
 | ||
|       }, 1000)();
 | ||
|     };
 | ||
|   });
 | ||
| </script>
 | ||
| {% endblock %}
 | ||
| 
 | ||
| {% block js %}
 | ||
| <script type="text/javascript" src="/js/session.js"></script>
 | ||
| <script type="text/javascript" src="/js/password.js"></script>
 | ||
| {% endblock %}
 |