90 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| {% extends "base_login_page.html" %}
 | |
| {% block content %}
 | |
| 
 | |
| <style>
 | |
| #otp input {
 | |
|   padding-left: 0px;
 | |
|   padding-right: 0px;
 | |
| }
 | |
| 
 | |
| </style>
 | |
| 
 | |
| <div>
 | |
|     <p>Please go to your authenticator app <i>{{ factor.name }}</i>, generate a new code and enter it here:</p>
 | |
|     <form id="totp_form" method="post" action="{{ factor.login_url(_p.redirect_uri) }}">
 | |
|         <input type="hidden" id="code" name="code"/>
 | |
|         <div class="form-group">
 | |
|             <div id="otp" class="inputs d-flex flex-row justify-content-center mt-2">
 | |
|                 <input class="m-2 text-center form-control rounded" type="text" id="i1" maxlength="1" autofocus/>
 | |
|                 <input class="m-2 text-center form-control rounded" type="text" id="i2" maxlength="1"/>
 | |
|                 <input class="m-2 text-center form-control rounded" type="text" id="i3" maxlength="1"/>
 | |
|                 <input class="m-2 text-center form-control rounded" type="text" id="i4" maxlength="1"/>
 | |
|                 <input class="m-2 text-center form-control rounded" type="text" id="i5" maxlength="1"/>
 | |
|                 <input class="m-2 text-center form-control rounded" type="text" id="i6" maxlength="1"/>
 | |
|             </div>
 | |
|         </div>
 | |
|     </form>
 | |
| </div>
 | |
| 
 | |
| 
 | |
| <div style="margin-top: 10px;">
 | |
|     <a href="/2fa_auth?force_display=true&redirect={{ _p.redirect_uri.get_encoded() }}">Sign in using another factor</a><br/>
 | |
|     <a href="/logout">Sign out</a>
 | |
| </div>
 | |
| 
 | |
| <script>
 | |
| function OTPInput() {
 | |
|     const inputs = document.querySelectorAll('#otp > *[id]');
 | |
|     for (let i = 0; i < inputs.length; i++) {
 | |
|         // Reset form on init
 | |
|         inputs[i].value = "";
 | |
|     }
 | |
| 
 | |
|     let currIndex = 0;
 | |
| 
 | |
|     document.addEventListener('keydown', (event) => {
 | |
|         if (event.key === "Backspace") {
 | |
|             if (inputs[currIndex].value != "") {
 | |
|                 inputs[currIndex].value = '';
 | |
|             } else if (currIndex > 0) {
 | |
|                 inputs[currIndex - 1].value = "";
 | |
|                 inputs[currIndex - 1].focus();
 | |
|                 currIndex--;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Code has already been typed entirely
 | |
|         else if (currIndex === inputs.length - 1 && inputs[currIndex].value !== '')
 | |
|         {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         // Add new digit
 | |
|         else if ((event.keyCode >= 48 && event.keyCode <= 57)
 | |
|             || (event.keyCode >= 96 && event.keyCode <= 105)){
 | |
|             inputs[currIndex].value = event.key;
 | |
|             if (currIndex < inputs.length - 1) {
 | |
|                 inputs[currIndex + 1].focus();
 | |
|                 currIndex++;
 | |
|             }
 | |
|             else
 | |
|                 submitCode();
 | |
|         }
 | |
| 
 | |
|         event.preventDefault();
 | |
|     });
 | |
| }
 | |
| 
 | |
| function submitCode() {
 | |
|     const code = [...document.querySelectorAll('#otp > *[id]')]
 | |
|         .map((i) => i.value)
 | |
|         .join("");
 | |
| 
 | |
|     document.getElementById("code").value = code;
 | |
|     document.getElementById("totp_form").submit();
 | |
| }
 | |
| 
 | |
| document.addEventListener("DOMContentLoaded", () => OTPInput());
 | |
| </script>
 | |
| 
 | |
| {% endblock content %} |