|
1 | | -<?php $page_name = 'Authentification à plusieurs facteurs'; ?> |
| 1 | +@php |
| 2 | + $etabName = DB::table('settings')->where('NAME', 'schoolName')->value('VALUE'); |
| 3 | + $etabType = DB::table('settings')->where('NAME', 'typeDim')->value('VALUE'); |
| 4 | + $page_name = "Authentification à plusieurs facteurs"; |
| 5 | +@endphp |
2 | 6 | <!DOCTYPE html> |
3 | 7 | <html :class="{ 'theme-dark': dark }" x-data="data()" lang="{{ str_replace('_', '-', app()->getLocale()) }}"> |
4 | 8 |
|
|
21 | 25 | Vérification supplémentaire |
22 | 26 | </h1> |
23 | 27 |
|
24 | | - <p class="mb-4 text-sm text-gray-600 dark:text-gray-500"> |
25 | | - <span class="font-bold">Bienvenue {{ Auth::user()->first_name . ' ' . Auth::user()->last_name }}</span>.<br/> |
| 28 | + <p class="mb-4 text-sm text-gray-500"> |
| 29 | + <span class="font-bold text-gray-600 dark:text-gray-400">Bienvenue {{ Auth::user()->first_name . ' ' . Auth::user()->last_name }}</span>.<br/> |
26 | 30 | Veuillez confirmer l'accès à votre compte en saisissant le code d'authentification fourni |
27 | 31 | par votre application d'authentification. |
28 | 32 | </p> |
|
31 | 35 |
|
32 | 36 | <x-auth-validation-errors :errors="$errors" /> |
33 | 37 |
|
34 | | - <form method="POST" action="{{ route('login.2fa') }}"> |
| 38 | + <form method="POST" action="{{ route('login.2fa') }}" id="otp_form"> |
35 | 39 | @csrf |
36 | | - |
37 | | - <label class="block text-sm"> |
38 | | - <span class="text-gray-700 dark:text-gray-400">Entrez le code OTP</span> |
39 | | - <input |
40 | | - class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input" |
41 | | - placeholder="012345" name="one_time_password" :value="old('one_time_password')" |
42 | | - type="code" inputmode="numeric" autocomplete="one-time-code" required autofocus /> |
43 | | - </label> |
| 40 | + <div class="flex justify-center items-center flex-col"> |
| 41 | + <div class="flex optfield"> |
| 42 | + <input class="disabled:opacity-50 w-11 text-3xl p-[10px] text-center rounded m-[2px] border-2 border-solid dark:border-gray-600 dark:bg-gray-700 border-gray-300 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray font-bold outline-none transition-all" type="text" maxlength="1" inputmode="numeric" autocomplete="one-time-code" autofocus /> |
| 43 | + <input class="disabled:opacity-50 w-11 text-3xl p-[10px] text-center rounded m-[2px] border-2 border-solid dark:border-gray-600 dark:bg-gray-700 border-gray-300 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray font-bold outline-none transition-all" type="text" maxlength="1" inputmode="numeric" /> |
| 44 | + <input class="disabled:opacity-50 w-11 text-3xl p-[10px] text-center rounded m-[2px] border-2 border-solid dark:border-gray-600 dark:bg-gray-700 border-gray-300 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray font-bold outline-none transition-all mr-4" type="text" maxlength="1" inputmode="numeric" /> |
| 45 | + <input class="disabled:opacity-50 w-11 text-3xl p-[10px] text-center rounded m-[2px] border-2 border-solid dark:border-gray-600 dark:bg-gray-700 border-gray-300 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray font-bold outline-none transition-all" type="text" maxlength="1" inputmode="numeric" /> |
| 46 | + <input class="disabled:opacity-50 w-11 text-3xl p-[10px] text-center rounded m-[2px] border-2 border-solid dark:border-gray-600 dark:bg-gray-700 border-gray-300 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray font-bold outline-none transition-all" type="text" maxlength="1" inputmode="numeric" /> |
| 47 | + <input class="disabled:opacity-50 w-11 text-3xl p-[10px] text-center rounded m-[2px] border-2 border-solid dark:border-gray-600 dark:bg-gray-700 border-gray-300 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray font-bold outline-none transition-all" type="text" maxlength="1" inputmode="numeric" /> |
| 48 | + </div> |
| 49 | + <input name="one_time_password" :value="old('one_time_password')" |
| 50 | + type="hidden" inputmode="numeric" required autocomplete="off" id="otp_hidden" /> |
| 51 | + </div> |
44 | 52 |
|
45 | 53 | <button |
46 | | - class="block w-full px-4 py-2 mt-4 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> |
| 54 | + class="disabled:opacity-50 block w-full px-4 py-2 mt-4 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> |
47 | 55 | Valider |
48 | 56 | </button> |
49 | 57 |
|
@@ -71,6 +79,64 @@ class="flex items-center justify-center w-full px-4 py-2 text-sm font-medium lea |
71 | 79 | </div> |
72 | 80 | </div> |
73 | 81 |
|
| 82 | + <script> |
| 83 | + const inputs = document.querySelectorAll(".optfield input"); |
| 84 | +
|
| 85 | + inputs.forEach((input, index) => { |
| 86 | + input.dataset.index = index; |
| 87 | + input.addEventListener("paste", handleOnPasteOtp); |
| 88 | + input.addEventListener("keyup", handleOtp); |
| 89 | + }) |
| 90 | +
|
| 91 | + function handleOnPasteOtp(e) { |
| 92 | + const data = e.clipboardData.getData("text"); |
| 93 | + const value = data.split(""); |
| 94 | + if (value.length === inputs.length) { |
| 95 | + inputs.forEach((input, index) => (input.value = value[index])); |
| 96 | + submit(); |
| 97 | + } |
| 98 | + } |
| 99 | +
|
| 100 | + function handleOtp(e) { |
| 101 | + const input = e.target; |
| 102 | + let value = input.value; |
| 103 | + input.value = ""; |
| 104 | + input.value = value ? value[0] : ""; |
| 105 | +
|
| 106 | + let fieldIndex = input.dataset.index; |
| 107 | + if (value.length > 0 && fieldIndex < inputs.length - 1) { |
| 108 | + input.nextElementSibling.focus(); |
| 109 | + } |
| 110 | +
|
| 111 | + if (e.key === "Backspace" && fieldIndex > 0) { |
| 112 | + input.previousElementSibling.focus(); |
| 113 | + } |
| 114 | +
|
| 115 | + if (fieldIndex == inputs.length - 1) { |
| 116 | + var completed = true; |
| 117 | + inputs.forEach((input) => { |
| 118 | + if(input.value == "") { |
| 119 | + completed = false; |
| 120 | + } |
| 121 | + }) |
| 122 | + if (completed) { |
| 123 | + submit(); |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | +
|
| 128 | + function submit() { |
| 129 | + console.log("Submitting..."); |
| 130 | + let otp = ""; |
| 131 | + inputs.forEach((input) => { |
| 132 | + otp += input.value; |
| 133 | + input.disabled = true; |
| 134 | + input.classList.add("disabled"); |
| 135 | + }); |
| 136 | + document.getElementById('otp_hidden').value = otp; |
| 137 | + document.getElementById('otp_form').submit(); |
| 138 | + } |
| 139 | + </script> |
74 | 140 | @include('layouts.footer') |
75 | 141 | </body> |
76 | 142 |
|
|
0 commit comments